From patchwork Wed Aug 21 07:25:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105753 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 3DFEB912 for ; Wed, 21 Aug 2019 07:27: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 148022332A for ; Wed, 21 Aug 2019 07:27: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="BytxYckJ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 148022332A 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]:44430 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L1t-0006cc-PE for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:27:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41950) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0G-0004On-Cx for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:25:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0E-0007st-Vv for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:25:56 -0400 Received: from ozlabs.org ([203.11.71.1]:53337) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0E-0007qS-1s; Wed, 21 Aug 2019 03:25:54 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46Czj85MMyz9sNC; Wed, 21 Aug 2019 17:25:48 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372348; bh=QhtAqHLfc/dTm4MprysS84S8YY7xN8GFeazUYfR9k1A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BytxYckJ2qZNoTCJ/0Tg1ClPF/iTYs3O/AdMVWlEnOKObXtpo5GiHFLS+9O9Ho5QV pJKfYsLHRr44aTPRNh2CglvFMjb6M+zmXd8YyufpfHjLqsWufRmSv6AgLbRFmNbhge 5rryHkI+Xqwxfd1bZDbLx5V8jDHDd4V7yQ56d6Jo= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:01 +1000 Message-Id: <20190821072542.23090-2-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 01/42] spapr: quantify error messages regarding capability settings 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, aik@ozlabs.ru, qemu-devel@nongnu.org, Daniel Black , groug@kaod.org, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Daniel Black Its not immediately obvious how cap-X=Y setting need to be applied to the command line so, for spapr capability error messages, this has been clarified to: appending -machine cap-X=Y The wrong value messages have been left as is, as the user has found the right location. Reviewed-by: Greg Kurz Signed-off-by: Daniel Black Message-Id: <20190812071044.30806-1-daniel@linux.ibm.com> Signed-off-by: David Gibson --- hw/ppc/spapr_caps.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index 7830d66d77..a61bf329bf 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -195,10 +195,12 @@ static void cap_htm_apply(SpaprMachineState *spapr, uint8_t val, Error **errp) } if (tcg_enabled()) { error_setg(errp, - "No Transactional Memory support in TCG, try cap-htm=off"); + "No Transactional Memory support in TCG," + " try appending -machine cap-htm=off"); } else if (kvm_enabled() && !kvmppc_has_cap_htm()) { error_setg(errp, -"KVM implementation does not support Transactional Memory, try cap-htm=off" +"KVM implementation does not support Transactional Memory," + " try appending -machine cap-htm=off" ); } } @@ -216,7 +218,8 @@ static void cap_vsx_apply(SpaprMachineState *spapr, uint8_t val, Error **errp) * rid of anything that doesn't do VMX */ g_assert(env->insns_flags & PPC_ALTIVEC); if (!(env->insns_flags2 & PPC2_VSX)) { - error_setg(errp, "VSX support not available, try cap-vsx=off"); + error_setg(errp, "VSX support not available," + " try appending -machine cap-vsx=off"); } } @@ -230,7 +233,8 @@ static void cap_dfp_apply(SpaprMachineState *spapr, uint8_t val, Error **errp) return; } if (!(env->insns_flags2 & PPC2_DFP)) { - error_setg(errp, "DFP support not available, try cap-dfp=off"); + error_setg(errp, "DFP support not available," + " try appending -machine cap-dfp=off"); } } @@ -254,7 +258,8 @@ static void cap_safe_cache_apply(SpaprMachineState *spapr, uint8_t val, cap_cfpc_possible.vals[val]); } else if (kvm_enabled() && (val > kvm_val)) { error_setg(errp, -"Requested safe cache capability level not supported by kvm, try cap-cfpc=%s", + "Requested safe cache capability level not supported by kvm," + " try appending -machine cap-cfpc=%s", cap_cfpc_possible.vals[kvm_val]); } @@ -282,7 +287,8 @@ static void cap_safe_bounds_check_apply(SpaprMachineState *spapr, uint8_t val, cap_sbbc_possible.vals[val]); } else if (kvm_enabled() && (val > kvm_val)) { error_setg(errp, -"Requested safe bounds check capability level not supported by kvm, try cap-sbbc=%s", +"Requested safe bounds check capability level not supported by kvm," + " try appending -machine cap-sbbc=%s", cap_sbbc_possible.vals[kvm_val]); } @@ -313,7 +319,8 @@ static void cap_safe_indirect_branch_apply(SpaprMachineState *spapr, cap_ibs_possible.vals[val]); } else if (kvm_enabled() && (val > kvm_val)) { error_setg(errp, -"Requested safe indirect branch capability level not supported by kvm, try cap-ibs=%s", +"Requested safe indirect branch capability level not supported by kvm," + " try appending -machine cap-ibs=%s", cap_ibs_possible.vals[kvm_val]); } @@ -402,11 +409,13 @@ static void cap_nested_kvm_hv_apply(SpaprMachineState *spapr, if (tcg_enabled()) { error_setg(errp, - "No Nested KVM-HV support in tcg, try cap-nested-hv=off"); + "No Nested KVM-HV support in tcg," + " try appending -machine cap-nested-hv=off"); } else if (kvm_enabled()) { if (!kvmppc_has_cap_nested_kvm_hv()) { error_setg(errp, -"KVM implementation does not support Nested KVM-HV, try cap-nested-hv=off"); +"KVM implementation does not support Nested KVM-HV," + " try appending -machine cap-nested-hv=off"); } else if (kvmppc_set_cap_nested_kvm_hv(val) < 0) { error_setg(errp, "Error enabling cap-nested-hv with KVM, try cap-nested-hv=off"); @@ -436,10 +445,12 @@ static void cap_large_decr_apply(SpaprMachineState *spapr, if (!kvm_nr_bits) { error_setg(errp, - "No large decrementer support, try cap-large-decr=off"); + "No large decrementer support," + " try appending -machine cap-large-decr=off"); } else if (pcc->lrg_decr_bits != kvm_nr_bits) { error_setg(errp, -"KVM large decrementer size (%d) differs to model (%d), try -cap-large-decr=off", +"KVM large decrementer size (%d) differs to model (%d)," + " try appending -machine cap-large-decr=off", kvm_nr_bits, pcc->lrg_decr_bits); } } @@ -455,7 +466,8 @@ static void cap_large_decr_cpu_apply(SpaprMachineState *spapr, if (kvm_enabled()) { if (kvmppc_enable_cap_large_decr(cpu, val)) { error_setg(errp, - "No large decrementer support, try cap-large-decr=off"); + "No large decrementer support," + " try appending -machine cap-large-decr=off"); } } @@ -475,10 +487,12 @@ static void cap_ccf_assist_apply(SpaprMachineState *spapr, uint8_t val, if (tcg_enabled() && val) { /* TODO - for now only allow broken for TCG */ error_setg(errp, -"Requested count cache flush assist capability level not supported by tcg, try cap-ccf-assist=off"); +"Requested count cache flush assist capability level not supported by tcg," + " try appending -machine cap-ccf-assist=off"); } else if (kvm_enabled() && (val > kvm_val)) { error_setg(errp, -"Requested count cache flush assist capability level not supported by kvm, try cap-ccf-assist=off"); +"Requested count cache flush assist capability level not supported by kvm," + " try appending -machine cap-ccf-assist=off"); } } From patchwork Wed Aug 21 07:25: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: 11105757 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 55A941399 for ; Wed, 21 Aug 2019 07:31:03 +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 2CAA22332A for ; Wed, 21 Aug 2019 07:31:03 +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="kP4hUtTR" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2CAA22332A 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]:44470 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L5B-0001dA-T3 for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:31:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41945) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0G-0004Om-3x for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:25:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0E-0007sh-V1 for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:25:56 -0400 Received: from ozlabs.org ([203.11.71.1]:43207) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0D-0007qP-V0; Wed, 21 Aug 2019 03:25:54 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46Czj849S9z9s3Z; Wed, 21 Aug 2019 17:25:48 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372348; bh=tOgL0zA9mNz9NzT5lhKuhdF4GsWgGJewvlTBKf1VtdM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kP4hUtTROjjme6uoTqs6rZQHroIXJYZgKYMlxo4Nt4i9m2DjeVYZS91wIfpWJ0wVC jwyqWhbOst3Xp2KEX66Bx0QFO+3cqGZJlWJtIVkq7HXj4mUnTT83nMLvhoznsLAsbl I/Fusyb22Ii6xC2YH7plC5chwZcyB7cUVXnTX2Qs= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:02 +1000 Message-Id: <20190821072542.23090-3-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 02/42] spapr_iommu: Fix xlate trace to print translated address 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, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.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: Alexey Kardashevskiy Currently we basically print IO address twice, fix this. Fixes: 7e472264e9e2 ("PPC: spapr: iommu: rework traces") Signed-off-by: Alexey Kardashevskiy Message-Id: <20190812054202.125492-1-aik@ozlabs.ru> Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/ppc/spapr_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c index ce85f8ac63..e87b3d50f7 100644 --- a/hw/ppc/spapr_iommu.c +++ b/hw/ppc/spapr_iommu.c @@ -136,7 +136,7 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(IOMMUMemoryRegion *iommu, ret.addr_mask = ~page_mask; ret.perm = spapr_tce_iommu_access_flags(tce); } - trace_spapr_iommu_xlate(tcet->liobn, addr, ret.iova, ret.perm, + trace_spapr_iommu_xlate(tcet->liobn, addr, ret.translated_addr, ret.perm, ret.addr_mask); return ret; From patchwork Wed Aug 21 07:25:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105789 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 D4C2E1399 for ; Wed, 21 Aug 2019 07:32:33 +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 A6E512332A for ; Wed, 21 Aug 2019 07:32:33 +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="Z69Q38IE" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A6E512332A 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]:44480 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L6e-000359-44 for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:32:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42089) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0M-0004Tc-Bu for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0K-0007zX-MZ for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:02 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:43563) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0J-0007sz-Qn; Wed, 21 Aug 2019 03:26:00 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46Czj9109Rz9sNk; Wed, 21 Aug 2019 17:25:48 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372349; bh=sRXk7SNRvroQ2qFl7AEBNqbIUZ7MSRvgK0vwUkIjtnY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Z69Q38IEtwqTqwKBbuh3qQ/2GsBw77JDb41a/mjzLfHB/pD3EkbyxyRNpveVhT9P4 dU4gtEsD3iB8fMErSWEN+XYmxK2HQsbm8JnF6xjpAt14cFzdVMuWhE5yoW5ggc1JBs jaO5v4AmBeqWvo04WpOHrUHpWFAE7btWFygaZNZ4= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:03 +1000 Message-Id: <20190821072542.23090-4-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 03/42] hw: add compat machines for 4.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, Eduardo Habkost , aik@ozlabs.ru, Cornelia Huck , qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Cornelia Huck Add 4.2 machine types for arm/i440fx/q35/s390x/spapr. For i440fx and q35, unversioned cpu models are still translated to -v1, as 0788a56bd1ae ("i386: Make unversioned CPU models be aliases") states this should only transition to the latest cpu model version in 4.3 (or later). Signed-off-by: Cornelia Huck Message-Id: <20190724103524.20916-1-cohuck@redhat.com> Reviewed-by: Eduardo Habkost Signed-off-by: David Gibson --- hw/arm/virt.c | 9 ++++++++- hw/core/machine.c | 3 +++ hw/i386/pc.c | 3 +++ hw/i386/pc_piix.c | 14 +++++++++++++- hw/i386/pc_q35.c | 13 ++++++++++++- hw/ppc/spapr.c | 15 +++++++++++++-- hw/s390x/s390-virtio-ccw.c | 14 +++++++++++++- include/hw/boards.h | 3 +++ include/hw/i386/pc.h | 3 +++ 9 files changed, 71 insertions(+), 6 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 02510acb81..0d1629ccb3 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -2050,10 +2050,17 @@ static void machvirt_machine_init(void) } type_init(machvirt_machine_init); +static void virt_machine_4_2_options(MachineClass *mc) +{ +} +DEFINE_VIRT_MACHINE_AS_LATEST(4, 2) + static void virt_machine_4_1_options(MachineClass *mc) { + virt_machine_4_2_options(mc); + compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len); } -DEFINE_VIRT_MACHINE_AS_LATEST(4, 1) +DEFINE_VIRT_MACHINE(4, 1) static void virt_machine_4_0_options(MachineClass *mc) { diff --git a/hw/core/machine.c b/hw/core/machine.c index 32d1ca9abc..83cd1bfeec 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -27,6 +27,9 @@ #include "hw/pci/pci.h" #include "hw/mem/nvdimm.h" +GlobalProperty hw_compat_4_1[] = {}; +const size_t hw_compat_4_1_len = G_N_ELEMENTS(hw_compat_4_1); + GlobalProperty hw_compat_4_0[] = { { "VGA", "edid", "false" }, { "secondary-vga", "edid", "false" }, diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 3ab4bcb3ca..95edbbfe9e 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -119,6 +119,9 @@ struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX}; /* Physical Address of PVH entry point read from kernel ELF NOTE */ static size_t pvh_start_addr; +GlobalProperty pc_compat_4_1[] = {}; +const size_t pc_compat_4_1_len = G_N_ELEMENTS(pc_compat_4_1); + GlobalProperty pc_compat_4_0[] = {}; const size_t pc_compat_4_0_len = G_N_ELEMENTS(pc_compat_4_0); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 9e187f856a..a70cf0aafc 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -432,7 +432,7 @@ static void pc_i440fx_machine_options(MachineClass *m) machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE); } -static void pc_i440fx_4_1_machine_options(MachineClass *m) +static void pc_i440fx_4_2_machine_options(MachineClass *m) { PCMachineClass *pcmc = PC_MACHINE_CLASS(m); pc_i440fx_machine_options(m); @@ -441,6 +441,18 @@ static void pc_i440fx_4_1_machine_options(MachineClass *m) pcmc->default_cpu_version = 1; } +DEFINE_I440FX_MACHINE(v4_2, "pc-i440fx-4.2", NULL, + pc_i440fx_4_2_machine_options); + +static void pc_i440fx_4_1_machine_options(MachineClass *m) +{ + pc_i440fx_4_2_machine_options(m); + m->alias = NULL; + m->is_default = 0; + compat_props_add(m->compat_props, hw_compat_4_1, hw_compat_4_1_len); + compat_props_add(m->compat_props, pc_compat_4_1, pc_compat_4_1_len); +} + DEFINE_I440FX_MACHINE(v4_1, "pc-i440fx-4.1", NULL, pc_i440fx_4_1_machine_options); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index be3464f485..d4e8a1cb9f 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -364,7 +364,7 @@ static void pc_q35_machine_options(MachineClass *m) m->max_cpus = 288; } -static void pc_q35_4_1_machine_options(MachineClass *m) +static void pc_q35_4_2_machine_options(MachineClass *m) { PCMachineClass *pcmc = PC_MACHINE_CLASS(m); pc_q35_machine_options(m); @@ -372,6 +372,17 @@ static void pc_q35_4_1_machine_options(MachineClass *m) pcmc->default_cpu_version = 1; } +DEFINE_Q35_MACHINE(v4_2, "pc-q35-4.2", NULL, + pc_q35_4_2_machine_options); + +static void pc_q35_4_1_machine_options(MachineClass *m) +{ + pc_q35_4_2_machine_options(m); + m->alias = NULL; + compat_props_add(m->compat_props, hw_compat_4_1, hw_compat_4_1_len); + compat_props_add(m->compat_props, pc_compat_4_1, pc_compat_4_1_len); +} + DEFINE_Q35_MACHINE(v4_1, "pc-q35-4.1", NULL, pc_q35_4_1_machine_options); diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index e09c67eb75..6587d9b559 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4430,15 +4430,26 @@ static const TypeInfo spapr_machine_info = { } \ type_init(spapr_machine_register_##suffix) +/* + * pseries-4.2 + */ +static void spapr_machine_4_2_class_options(MachineClass *mc) +{ + /* Defaults for the latest behaviour inherited from the base class */ +} + +DEFINE_SPAPR_MACHINE(4_2, "4.2", true); + /* * pseries-4.1 */ static void spapr_machine_4_1_class_options(MachineClass *mc) { - /* Defaults for the latest behaviour inherited from the base class */ + spapr_machine_4_2_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len); } -DEFINE_SPAPR_MACHINE(4_1, "4.1", true); +DEFINE_SPAPR_MACHINE(4_1, "4.1", false); /* * pseries-4.0 diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 434d933ec9..8bfb6684cb 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -663,14 +663,26 @@ bool css_migration_enabled(void) } \ type_init(ccw_machine_register_##suffix) +static void ccw_machine_4_2_instance_options(MachineState *machine) +{ +} + +static void ccw_machine_4_2_class_options(MachineClass *mc) +{ +} +DEFINE_CCW_MACHINE(4_2, "4.2", true); + static void ccw_machine_4_1_instance_options(MachineState *machine) { + ccw_machine_4_2_instance_options(machine); } static void ccw_machine_4_1_class_options(MachineClass *mc) { + ccw_machine_4_2_class_options(mc); + compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len); } -DEFINE_CCW_MACHINE(4_1, "4.1", true); +DEFINE_CCW_MACHINE(4_1, "4.1", false); static void ccw_machine_4_0_instance_options(MachineState *machine) { diff --git a/include/hw/boards.h b/include/hw/boards.h index 739d109fe1..aa35955f7f 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -317,6 +317,9 @@ struct MachineState { } \ type_init(machine_initfn##_register_types) +extern GlobalProperty hw_compat_4_1[]; +extern const size_t hw_compat_4_1_len; + extern GlobalProperty hw_compat_4_0[]; extern const size_t hw_compat_4_0_len; diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 4bb9e29114..ec538df9b7 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -301,6 +301,9 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); int e820_get_num_entries(void); bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); +extern GlobalProperty pc_compat_4_1[]; +extern const size_t pc_compat_4_1_len; + extern GlobalProperty pc_compat_4_0[]; extern const size_t pc_compat_4_0_len; From patchwork Wed Aug 21 07:25:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105749 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 CD0A9912 for ; Wed, 21 Aug 2019 07:27:31 +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 A41BA2332A for ; Wed, 21 Aug 2019 07:27:31 +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="IZ7xWkTK" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A41BA2332A 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]:44426 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L1m-0006SB-Hz for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:27:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41942) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0G-0004Ol-42 for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:25:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0E-0007so-W6 for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:25:55 -0400 Received: from ozlabs.org ([203.11.71.1]:46439) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0E-0007qR-4p; Wed, 21 Aug 2019 03:25:54 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46Czj8724gz9sNm; Wed, 21 Aug 2019 17:25:48 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372348; bh=s3rP9nOYw6dbdVMOG48CakC3NHOqA8jLpQtmp70iOPY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IZ7xWkTKythI5rZJ3biZJ6SrrGXgDv7Cki0dXLwoOYeyIikB4+G2iqCN9BHnA+USf 1Ix9/YkwjEr26IZtDXLcS/Q4HQehV0L4Ag8dbV20gS7MZ/sq/EZgcYUpCk2IWTYUjP UEgodGWK72bvpjlP9jHaIqAnyIMmIBBEv/w7bF48= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:04 +1000 Message-Id: <20190821072542.23090-5-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 04/42] spapr_pci: Allow 2MiB and 16MiB IOMMU pagesizes by default 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, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" We've had the qemu and kernel KVM infrastructure to handle larger TCE page sizes for a while, but forgot to update the defaults to actually allow them. This turns that change on. Signed-off-by: David Gibson --- hw/ppc/spapr.c | 6 ++++++ hw/ppc/spapr_pci.c | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 6587d9b559..22a45c3737 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4445,8 +4445,14 @@ DEFINE_SPAPR_MACHINE(4_2, "4.2", true); */ static void spapr_machine_4_1_class_options(MachineClass *mc) { + static GlobalProperty compat[] = { + /* Only allow 4kiB and 64kiB IOMMU pagesizes */ + { TYPE_SPAPR_PCI_HOST_BRIDGE, "pgsz", "0x11000" }, + }; + spapr_machine_4_2_class_options(mc); 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)); } DEFINE_SPAPR_MACHINE(4_1, "4.1", false); diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index bf31fd854c..4c5420c465 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -2093,7 +2093,8 @@ static Property spapr_phb_properties[] = { 0x800000000000000ULL), DEFINE_PROP_BOOL("ddw", SpaprPhbState, ddw_enabled, true), DEFINE_PROP_UINT64("pgsz", SpaprPhbState, page_size_mask, - (1ULL << 12) | (1ULL << 16)), + (1ULL << 12) | (1ULL << 16) + | (1ULL << 21) | (1ULL << 24)), DEFINE_PROP_UINT32("numa_node", SpaprPhbState, numa_node, -1), DEFINE_PROP_BOOL("pre-2.8-migration", SpaprPhbState, pre_2_8_migration, false), From patchwork Wed Aug 21 07:25: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: 11105751 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 59EE41813 for ; Wed, 21 Aug 2019 07:27:35 +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 2EBDA233A1 for ; Wed, 21 Aug 2019 07:27: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="d1xqWc7e" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2EBDA233A1 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]:44428 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L1p-0006W6-TY for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:27:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:41939) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0G-0004Oj-21 for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:25:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0E-0007sX-Qx for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:25:55 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:53363) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0E-0007qM-Ag; Wed, 21 Aug 2019 03:25:54 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46Czj86LCYz9sN6; Wed, 21 Aug 2019 17:25:48 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372348; bh=aw5W83RgbqJeiMgkHYQ5Rg2X9vFhxMjn+uUovii8P/A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=d1xqWc7e50udB77cS0IHhRo/aoj8z3dMVpuENTiBdPrAfJrU3dtGBBkwPEHjU/UuM yyVEwGfzto49GPnvS4dRE4wfP4lieyiQyZxRUH5wJ2dteVcro28yELutpIDe6j/Hdu G9F78koQwlI9vSaVPud6vA+/bSljeSjAYW9WPx08= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:05 +1000 Message-Id: <20190821072542.23090-6-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 05/42] migration: Do not re-read the clock on pre_save in case of paused guest 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, aik@ozlabs.ru, qemu-devel@nongnu.org, "Maxiwell S. Garcia" , groug@kaod.org, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: "Maxiwell S. Garcia" Re-read the timebase before migrate was ported from x86 commit: 6053a86fe7bd: kvmclock: reduce kvmclock difference on migration The clock move makes the guest knows about the paused time between the stop and migrate commands. This is an issue in an already-paused VM because some side effects, like process stalls, could happen after migration. So, this patch checks the runstate of guest in the pre_save handler and do not re-reads the timebase in case of paused state (cold migration). Signed-off-by: Maxiwell S. Garcia Message-Id: <20190711194702.26598-1-maxiwell@linux.ibm.com> Signed-off-by: David Gibson --- hw/ppc/ppc.c | 13 +++++++++---- target/ppc/cpu-qom.h | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index 7963feeab4..52a18eb7d7 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -1011,6 +1011,8 @@ static void timebase_save(PPCTimebase *tb) * there is no need to update it from KVM here */ tb->guest_timebase = ticks + first_ppc_cpu->env.tb_env->tb_offset; + + tb->runstate_paused = runstate_check(RUN_STATE_PAUSED); } static void timebase_load(PPCTimebase *tb) @@ -1054,9 +1056,9 @@ void cpu_ppc_clock_vm_state_change(void *opaque, int running, } /* - * When migrating, read the clock just before migration, - * so that the guest clock counts during the events - * between: + * When migrating a running guest, read the clock just + * before migration, so that the guest clock counts + * during the events between: * * * vm_stop() * * @@ -1071,7 +1073,10 @@ static int timebase_pre_save(void *opaque) { PPCTimebase *tb = opaque; - timebase_save(tb); + /* guest_timebase won't be overridden in case of paused guest */ + if (!tb->runstate_paused) { + timebase_save(tb); + } return 0; } diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h index a2f202f021..5769fb78a9 100644 --- a/target/ppc/cpu-qom.h +++ b/target/ppc/cpu-qom.h @@ -201,6 +201,7 @@ typedef struct PowerPCCPUClass { typedef struct PPCTimebase { uint64_t guest_timebase; int64_t time_of_the_day_ns; + bool runstate_paused; } PPCTimebase; extern const VMStateDescription vmstate_ppc_timebase; From patchwork Wed Aug 21 07:25:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105827 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 83FA1912 for ; Wed, 21 Aug 2019 07:40:12 +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 5654822CE3 for ; Wed, 21 Aug 2019 07:40:12 +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="ebayNIsB" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5654822CE3 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]:44544 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LE3-0003za-0o for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:40:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42096) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0M-0004U0-K3 for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0K-0007zl-QY for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:02 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:51469) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0K-0007tX-0s; Wed, 21 Aug 2019 03:26:00 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46Czj959KKz9sP7; Wed, 21 Aug 2019 17:25:48 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372349; bh=IJjvyAJRI8Nn3VKxWazB60FQBl2Ny9jjhlwsGiGZ5Qs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ebayNIsBq2gP1ZY0aCumZIx+r/i6UGxk3Grx6PCVuNDTSeoUg1JKi1bD1sTtO0un3 bYzfgRugniy8rbwGlqHyjypG+6Ti0LTSl9blw7/c2YZlHthyUQecTOYoRp/osGWFik dFf0SNB9V/m/sX/kmmuAORUmcfK7nQ83N/GNDRTU= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:06 +1000 Message-Id: <20190821072542.23090-7-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 06/42] target/ppc: Optimize emulation of lvsl and lvsr instructions 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, aik@ozlabs.ru, Richard Henderson , qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, Stefan Brankovic , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Stefan Brankovic Adding simple macro that is calling tcg implementation of appropriate instruction if altivec support is active. Optimization of altivec instruction lvsl (Load Vector for Shift Left). Place bytes sh:sh+15 of value 0x00 || 0x01 || 0x02 || ... || 0x1E || 0x1F in destination register. Sh is calculated by adding 2 source registers and getting bits 60-63 of result. First, the bits [28-31] are placed from EA to variable sh. After that, the bytes are created in the following way: sh:(sh+7) of X(from description) by multiplying sh with 0x0101010101010101 followed by addition of the result with 0x0001020304050607. Value obtained is placed in higher doubleword element of vD. (sh+8):(sh+15) by adding the result of previous multiplication with 0x08090a0b0c0d0e0f. Value obtained is placed in lower doubleword element of vD. Optimization of altivec instruction lvsr (Load Vector for Shift Right). Place bytes 16-sh:31-sh of value 0x00 || 0x01 || 0x02 || ... || 0x1E || 0x1F in destination register. Sh is calculated by adding 2 source registers and getting bits 60-63 of result. First, the bits [28-31] are placed from EA to variable sh. After that, the bytes are created in the following way: sh:(sh+7) of X(from description) by multiplying sh with 0x0101010101010101 followed by substraction of the result from 0x1011121314151617. Value obtained is placed in higher doubleword element of vD. (sh+8):(sh+15) by substracting the result of previous multiplication from 0x18191a1b1c1d1e1f. Value obtained is placed in lower doubleword element of vD. Signed-off-by: Stefan Brankovic Reviewed-by: Richard Henderson Message-Id: <1563200574-11098-2-git-send-email-stefan.brankovic@rt-rk.com> Signed-off-by: David Gibson --- target/ppc/helper.h | 2 - target/ppc/int_helper.c | 18 ----- target/ppc/translate/vmx-impl.inc.c | 121 ++++++++++++++++++++-------- 3 files changed, 89 insertions(+), 52 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 380c9b1e2a..121d7868d0 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -193,8 +193,6 @@ DEF_HELPER_2(vprtybw, void, avr, avr) DEF_HELPER_2(vprtybd, void, avr, avr) DEF_HELPER_2(vprtybq, void, avr, avr) DEF_HELPER_3(vsubcuw, void, avr, avr, avr) -DEF_HELPER_2(lvsl, void, avr, tl) -DEF_HELPER_2(lvsr, void, avr, tl) DEF_HELPER_FLAGS_5(vaddsbs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_5(vaddshs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_5(vaddsws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 8f037af956..5dcca5362b 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -459,24 +459,6 @@ SATCVT(sd, uw, int64_t, uint32_t, 0, UINT32_MAX) #undef SATCVT #undef SATCVTU -void helper_lvsl(ppc_avr_t *r, target_ulong sh) -{ - int i, j = (sh & 0xf); - - for (i = 0; i < ARRAY_SIZE(r->u8); i++) { - r->VsrB(i) = j++; - } -} - -void helper_lvsr(ppc_avr_t *r, target_ulong sh) -{ - int i, j = 0x10 - (sh & 0xf); - - for (i = 0; i < ARRAY_SIZE(r->u8); i++) { - r->VsrB(i) = j++; - } -} - void helper_mtvscr(CPUPPCState *env, uint32_t vscr) { env->vscr = vscr & ~(1u << VSCR_SAT); diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index 663275b729..a9fe3c7834 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -142,38 +142,6 @@ GEN_VR_STVE(bx, 0x07, 0x04, 1); GEN_VR_STVE(hx, 0x07, 0x05, 2); GEN_VR_STVE(wx, 0x07, 0x06, 4); -static void gen_lvsl(DisasContext *ctx) -{ - TCGv_ptr rd; - TCGv EA; - if (unlikely(!ctx->altivec_enabled)) { - gen_exception(ctx, POWERPC_EXCP_VPU); - return; - } - EA = tcg_temp_new(); - gen_addr_reg_index(ctx, EA); - rd = gen_avr_ptr(rD(ctx->opcode)); - gen_helper_lvsl(rd, EA); - tcg_temp_free(EA); - tcg_temp_free_ptr(rd); -} - -static void gen_lvsr(DisasContext *ctx) -{ - TCGv_ptr rd; - TCGv EA; - if (unlikely(!ctx->altivec_enabled)) { - gen_exception(ctx, POWERPC_EXCP_VPU); - return; - } - EA = tcg_temp_new(); - gen_addr_reg_index(ctx, EA); - rd = gen_avr_ptr(rD(ctx->opcode)); - gen_helper_lvsr(rd, EA); - tcg_temp_free(EA); - tcg_temp_free_ptr(rd); -} - static void gen_mfvscr(DisasContext *ctx) { TCGv_i32 t; @@ -316,6 +284,16 @@ static void glue(gen_, name)(DisasContext *ctx) \ tcg_temp_free_ptr(rd); \ } +#define GEN_VXFORM_TRANS(name, opc2, opc3) \ +static void glue(gen_, name)(DisasContext *ctx) \ +{ \ + if (unlikely(!ctx->altivec_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VPU); \ + return; \ + } \ + trans_##name(ctx); \ +} + #define GEN_VXFORM_ENV(name, opc2, opc3) \ static void glue(gen_, name)(DisasContext *ctx) \ { \ @@ -515,6 +493,83 @@ static void gen_vmrgow(DisasContext *ctx) tcg_temp_free_i64(avr); } +/* + * lvsl VRT,RA,RB - Load Vector for Shift Left + * + * Let the EA be the sum (rA|0)+(rB). Let sh=EA[28–31]. + * Let X be the 32-byte value 0x00 || 0x01 || 0x02 || ... || 0x1E || 0x1F. + * Bytes sh:sh+15 of X are placed into vD. + */ +static void trans_lvsl(DisasContext *ctx) +{ + int VT = rD(ctx->opcode); + TCGv_i64 result = tcg_temp_new_i64(); + TCGv_i64 sh = tcg_temp_new_i64(); + TCGv EA = tcg_temp_new(); + + /* Get sh(from description) by anding EA with 0xf. */ + gen_addr_reg_index(ctx, EA); + tcg_gen_extu_tl_i64(sh, EA); + tcg_gen_andi_i64(sh, sh, 0xfULL); + + /* + * Create bytes sh:sh+7 of X(from description) and place them in + * higher doubleword of vD. + */ + tcg_gen_muli_i64(sh, sh, 0x0101010101010101ULL); + tcg_gen_addi_i64(result, sh, 0x0001020304050607ull); + set_avr64(VT, result, true); + /* + * Create bytes sh+8:sh+15 of X(from description) and place them in + * lower doubleword of vD. + */ + tcg_gen_addi_i64(result, sh, 0x08090a0b0c0d0e0fULL); + set_avr64(VT, result, false); + + tcg_temp_free_i64(result); + tcg_temp_free_i64(sh); + tcg_temp_free(EA); +} + +/* + * lvsr VRT,RA,RB - Load Vector for Shift Right + * + * Let the EA be the sum (rA|0)+(rB). Let sh=EA[28–31]. + * Let X be the 32-byte value 0x00 || 0x01 || 0x02 || ... || 0x1E || 0x1F. + * Bytes (16-sh):(31-sh) of X are placed into vD. + */ +static void trans_lvsr(DisasContext *ctx) +{ + int VT = rD(ctx->opcode); + TCGv_i64 result = tcg_temp_new_i64(); + TCGv_i64 sh = tcg_temp_new_i64(); + TCGv EA = tcg_temp_new(); + + + /* Get sh(from description) by anding EA with 0xf. */ + gen_addr_reg_index(ctx, EA); + tcg_gen_extu_tl_i64(sh, EA); + tcg_gen_andi_i64(sh, sh, 0xfULL); + + /* + * Create bytes (16-sh):(23-sh) of X(from description) and place them in + * higher doubleword of vD. + */ + tcg_gen_muli_i64(sh, sh, 0x0101010101010101ULL); + tcg_gen_subfi_i64(result, 0x1011121314151617ULL, sh); + set_avr64(VT, result, true); + /* + * Create bytes (24-sh):(32-sh) of X(from description) and place them in + * lower doubleword of vD. + */ + tcg_gen_subfi_i64(result, 0x18191a1b1c1d1e1fULL, sh); + set_avr64(VT, result, false); + + tcg_temp_free_i64(result); + tcg_temp_free_i64(sh); + tcg_temp_free(EA); +} + GEN_VXFORM(vmuloub, 4, 0); GEN_VXFORM(vmulouh, 4, 1); GEN_VXFORM(vmulouw, 4, 2); @@ -662,6 +717,8 @@ GEN_VXFORM_DUAL(vmrgow, PPC_NONE, PPC2_ALTIVEC_207, GEN_VXFORM_HETRO(vextubrx, 6, 28) GEN_VXFORM_HETRO(vextuhrx, 6, 29) GEN_VXFORM_HETRO(vextuwrx, 6, 30) +GEN_VXFORM_TRANS(lvsl, 6, 31) +GEN_VXFORM_TRANS(lvsr, 6, 32) GEN_VXFORM_DUAL(vmrgew, PPC_NONE, PPC2_ALTIVEC_207, \ vextuwrx, PPC_NONE, PPC2_ISA300) From patchwork Wed Aug 21 07:25:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105833 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 BEA6D912 for ; Wed, 21 Aug 2019 07:41:33 +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 26CFE2339F for ; Wed, 21 Aug 2019 07:41:33 +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="few4hEf6" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 26CFE2339F 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]:44562 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LFL-0006fC-Qj for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:41:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42086) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0M-0004TY-8n for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0K-0007zE-DD for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:02 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:38203) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0J-0007tA-Mv; Wed, 21 Aug 2019 03:26:00 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46Czj93d4qz9sPG; Wed, 21 Aug 2019 17:25:48 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372349; bh=kYrwrHDGsqHYYDsnZUEggVz/9A6beTZ/ZYAXuq0uvho=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=few4hEf6HGQVUibWxSKAIWC0zpVrYywzGUUgAahA9Hd6rgpqOL5Ai78+QV8wsQd9d c5Gieri89OX4Sb7tMkWCtj3lXy+mxAzh2PVkTyaH2SqaW1n5g9ti/6m3H+0mJp2m5q Ae+KMdNG84nQ67WnzAGtI5ePKO5kXE55OF9gkf+4= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:07 +1000 Message-Id: <20190821072542.23090-8-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 07/42] target/ppc: Optimize emulation of vsl and vsr instructions 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, aik@ozlabs.ru, Richard Henderson , qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, Stefan Brankovic , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Stefan Brankovic Optimization of altivec instructions vsl and vsr(Vector Shift Left/Rigt). Perform shift operation (left and right respectively) on 128 bit value of register vA by value specified in bits 125-127 of register vB. Lowest 3 bits in each byte element of register vB must be identical or result is undefined. For vsl instruction, the first step is bits 125-127 of register vB have to be saved in variable sh. Then, the highest sh bits of the lower doubleword element of register vA are saved in variable shifted, in order not to lose those bits when shift operation is performed on the lower doubleword element of register vA, which is the next step. After shifting the lower doubleword element shift operation is performed on higher doubleword element of vA, with replacement of the lowest sh bits(that are now 0) with bits saved in shifted. For vsr instruction, firstly, the bits 125-127 of register vB have to be saved in variable sh. Then, the lowest sh bits of the higher doubleword element of register vA are saved in variable shifted, in odred not to lose those bits when the shift operation is performed on the higher doubleword element of register vA, which is the next step. After shifting higher doubleword element, shift operation is performed on lower doubleword element of vA, with replacement of highest sh bits(that are now 0) with bits saved in shifted. Signed-off-by: Stefan Brankovic Reviewed-by: Richard Henderson Message-Id: <1563200574-11098-3-git-send-email-stefan.brankovic@rt-rk.com> Signed-off-by: David Gibson --- target/ppc/helper.h | 2 - target/ppc/int_helper.c | 35 ---------- target/ppc/translate/vmx-impl.inc.c | 101 +++++++++++++++++++++++++++- 3 files changed, 99 insertions(+), 39 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 121d7868d0..6fb823c7b4 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -217,8 +217,6 @@ DEF_HELPER_3(vrlb, void, avr, avr, avr) DEF_HELPER_3(vrlh, void, avr, avr, avr) DEF_HELPER_3(vrlw, void, avr, avr, avr) DEF_HELPER_3(vrld, void, avr, avr, avr) -DEF_HELPER_3(vsl, void, avr, avr, avr) -DEF_HELPER_3(vsr, void, avr, avr, avr) DEF_HELPER_4(vsldoi, void, avr, avr, avr, i32) DEF_HELPER_3(vextractub, void, avr, avr, i32) DEF_HELPER_3(vextractuh, void, avr, avr, i32) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 5dcca5362b..d2cad787ad 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -1740,41 +1740,6 @@ VEXTU_X_DO(vextuhrx, 16, 0) VEXTU_X_DO(vextuwrx, 32, 0) #undef VEXTU_X_DO -/* - * The specification says that the results are undefined if all of the - * shift counts are not identical. We check to make sure that they - * are to conform to what real hardware appears to do. - */ -#define VSHIFT(suffix, leftp) \ - void helper_vs##suffix(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ - { \ - int shift = b->VsrB(15) & 0x7; \ - int doit = 1; \ - int i; \ - \ - for (i = 0; i < ARRAY_SIZE(r->u8); i++) { \ - doit = doit && ((b->u8[i] & 0x7) == shift); \ - } \ - if (doit) { \ - if (shift == 0) { \ - *r = *a; \ - } else if (leftp) { \ - uint64_t carry = a->VsrD(1) >> (64 - shift); \ - \ - r->VsrD(0) = (a->VsrD(0) << shift) | carry; \ - r->VsrD(1) = a->VsrD(1) << shift; \ - } else { \ - uint64_t carry = a->VsrD(0) << (64 - shift); \ - \ - r->VsrD(1) = (a->VsrD(1) >> shift) | carry; \ - r->VsrD(0) = a->VsrD(0) >> shift; \ - } \ - } \ - } -VSHIFT(l, 1) -VSHIFT(r, 0) -#undef VSHIFT - void helper_vslv(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) { int i; diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index a9fe3c7834..e06e65adb2 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -570,6 +570,103 @@ static void trans_lvsr(DisasContext *ctx) tcg_temp_free(EA); } +/* + * vsl VRT,VRA,VRB - Vector Shift Left + * + * Shifting left 128 bit value of vA by value specified in bits 125-127 of vB. + * Lowest 3 bits in each byte element of register vB must be identical or + * result is undefined. + */ +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 sh = tcg_temp_new_i64(); + TCGv_i64 shifted = 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); + + /* + * Save highest sh bits of lower doubleword element of vA in variable + * shifted 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); + + /* + * Perform shift on higher doubleword element of vA and replace lowest + * sh bits with shifted. + */ + get_avr64(avrA, VA, true); + tcg_gen_shl_i64(avrA, avrA, sh); + tcg_gen_or_i64(avrA, avrA, shifted); + set_avr64(VT, avrA, true); + + tcg_temp_free_i64(avrA); + tcg_temp_free_i64(avrB); + tcg_temp_free_i64(sh); + tcg_temp_free_i64(shifted); + tcg_temp_free_i64(tmp); +} + +/* + * vsr VRT,VRA,VRB - Vector Shift Right + * + * Shifting right 128 bit value of vA by value specified in bits 125-127 of vB. + * Lowest 3 bits in each byte element of register vB must be identical or + * result is undefined. + */ +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 sh = tcg_temp_new_i64(); + TCGv_i64 shifted = 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); + + /* + * Save lowest sh bits of higher doubleword element of vA in variable + * shifted 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); + /* + * Perform shift on lower doubleword element of vA and replace highest + * sh bits with shifted. + */ + get_avr64(avrA, VA, false); + tcg_gen_shr_i64(avrA, avrA, sh); + tcg_gen_or_i64(avrA, avrA, shifted); + set_avr64(VT, avrA, false); + + tcg_temp_free_i64(avrA); + tcg_temp_free_i64(avrB); + tcg_temp_free_i64(sh); + tcg_temp_free_i64(shifted); + tcg_temp_free_i64(tmp); +} + GEN_VXFORM(vmuloub, 4, 0); GEN_VXFORM(vmulouh, 4, 1); GEN_VXFORM(vmulouw, 4, 2); @@ -682,11 +779,11 @@ GEN_VXFORM(vrld, 2, 3); GEN_VXFORM(vrldmi, 2, 3); GEN_VXFORM_DUAL(vrld, PPC_NONE, PPC2_ALTIVEC_207, \ vrldmi, PPC_NONE, PPC2_ISA300) -GEN_VXFORM(vsl, 2, 7); +GEN_VXFORM_TRANS(vsl, 2, 7); GEN_VXFORM(vrldnm, 2, 7); GEN_VXFORM_DUAL(vsl, PPC_ALTIVEC, PPC_NONE, \ vrldnm, PPC_NONE, PPC2_ISA300) -GEN_VXFORM(vsr, 2, 11); +GEN_VXFORM_TRANS(vsr, 2, 11); GEN_VXFORM_ENV(vpkuhum, 7, 0); GEN_VXFORM_ENV(vpkuwum, 7, 1); GEN_VXFORM_ENV(vpkudum, 7, 17); From patchwork Wed Aug 21 07:25: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: 11105821 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 DAC39912 for ; Wed, 21 Aug 2019 07:37: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 AE0C522CE3 for ; Wed, 21 Aug 2019 07:37: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="STvSz3V7" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AE0C522CE3 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]:44510 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LBA-0008UC-Bn for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:37:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42095) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0M-0004Tr-JE for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0K-0007zd-P2 for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:02 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:48573) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0J-0007tU-WA; Wed, 21 Aug 2019 03:26:00 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46Czj94QDHz9sP3; Wed, 21 Aug 2019 17:25:49 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372349; bh=XqyhbOl/gxAdC8MJ8BVPV9g2FOc7Ped5PieEArgy48k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=STvSz3V72iqhpPC6EvXckAeQviXBGOtwtXcUt2TWXq7YwI11Zpj08eOpMQu/zhhgM A+VuezACU9iLtmxcJMkQ9QVTcL80Ce/YzTlLNL/naLA4MBjhJp0acb5s98QbyGlYGI lagI3EhW+TTyifITE/nQXqvc7fVPpe3kckf3WWj8= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:08 +1000 Message-Id: <20190821072542.23090-9-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 08/42] target/ppc: move opcode decode tables to PowerPCCPU 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, aik@ozlabs.ru, Richard Henderson , 1836558@bugs.launchpad.net, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, =?utf-8?q?Alex_?= =?utf-8?q?Benn=C3=A9e?= , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Alex Bennée The opcode decode tables aren't really part of the CPUPPCState but an internal implementation detail for the translator. This can cause problems with memcpy in cpu_copy as any table created during ppc_cpu_realize get written over causing a memory leak. To avoid this move the tables into PowerPCCPU which is better suited to hold internal implementation details. Attempts to fix: https://bugs.launchpad.net/qemu/+bug/1836558 Cc: 1836558@bugs.launchpad.net Signed-off-by: Alex Bennée Message-Id: <20190716121352.302-1-alex.bennee@linaro.org> Reviewed-by: Richard Henderson Signed-off-by: David Gibson --- target/ppc/cpu.h | 8 ++++---- target/ppc/translate.c | 3 ++- target/ppc/translate_init.inc.c | 16 +++++++--------- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 4ea33cf696..630a25c246 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1104,10 +1104,6 @@ struct CPUPPCState { bool resume_as_sreset; #endif - /* Those resources are used only during code translation */ - /* opcode handlers */ - opc_handler_t *opcodes[PPC_CPU_OPCODES_LEN]; - /* Those resources are used only in QEMU core */ target_ulong hflags; /* hflags is a MSR & HFLAGS_MASK */ target_ulong hflags_nmsr; /* specific hflags, not coming from MSR */ @@ -1191,6 +1187,10 @@ struct PowerPCCPU { int32_t node_id; /* NUMA node this CPU belongs to */ PPCHash64Options *hash64_opts; + /* Those resources are used only during code translation */ + /* opcode handlers */ + opc_handler_t *opcodes[PPC_CPU_OPCODES_LEN]; + /* Fields related to migration compatibility hacks */ bool pre_2_8_migration; target_ulong mig_msr_mask; diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 9f9553afb4..1afb31e855 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -7858,6 +7858,7 @@ static bool ppc_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs, static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) { DisasContext *ctx = container_of(dcbase, DisasContext, base); + PowerPCCPU *cpu = POWERPC_CPU(cs); CPUPPCState *env = cs->env_ptr; opc_handler_t **table, *handler; @@ -7875,7 +7876,7 @@ static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) opc3(ctx->opcode), opc4(ctx->opcode), ctx->le_mode ? "little" : "big"); ctx->base.pc_next += 4; - table = env->opcodes; + table = cpu->opcodes; handler = table[opc1(ctx->opcode)]; if (is_indirect_opcode(handler)) { table = ind_table(handler); diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index 86fc8f2e31..9cd2033bb9 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -9440,14 +9440,13 @@ static void fix_opcode_tables(opc_handler_t **ppc_opcodes) static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp) { PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); - CPUPPCState *env = &cpu->env; opcode_t *opc; - fill_new_table(env->opcodes, PPC_CPU_OPCODES_LEN); + fill_new_table(cpu->opcodes, PPC_CPU_OPCODES_LEN); for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) { if (((opc->handler.type & pcc->insns_flags) != 0) || ((opc->handler.type2 & pcc->insns_flags2) != 0)) { - if (register_insn(env->opcodes, opc) < 0) { + if (register_insn(cpu->opcodes, opc) < 0) { error_setg(errp, "ERROR initializing PowerPC instruction " "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2, opc->opc3); @@ -9455,7 +9454,7 @@ static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp) } } } - fix_opcode_tables(env->opcodes); + fix_opcode_tables(cpu->opcodes); fflush(stdout); fflush(stderr); } @@ -10023,7 +10022,6 @@ static void ppc_cpu_unrealize(DeviceState *dev, Error **errp) { PowerPCCPU *cpu = POWERPC_CPU(dev); PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); - CPUPPCState *env = &cpu->env; Error *local_err = NULL; opc_handler_t **table, **table_2; int i, j, k; @@ -10035,11 +10033,11 @@ static void ppc_cpu_unrealize(DeviceState *dev, Error **errp) } for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) { - if (env->opcodes[i] == &invalid_handler) { + if (cpu->opcodes[i] == &invalid_handler) { continue; } - if (is_indirect_opcode(env->opcodes[i])) { - table = ind_table(env->opcodes[i]); + if (is_indirect_opcode(cpu->opcodes[i])) { + table = ind_table(cpu->opcodes[i]); for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) { if (table[j] == &invalid_handler) { continue; @@ -10057,7 +10055,7 @@ static void ppc_cpu_unrealize(DeviceState *dev, Error **errp) ~PPC_INDIRECT)); } } - g_free((opc_handler_t *)((uintptr_t)env->opcodes[i] & + g_free((opc_handler_t *)((uintptr_t)cpu->opcodes[i] & ~PPC_INDIRECT)); } } From patchwork Wed Aug 21 07:25:09 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105755 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 77D74912 for ; Wed, 21 Aug 2019 07:28:17 +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 3E7F02332A for ; Wed, 21 Aug 2019 07:28:17 +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="OYOQUEnt" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3E7F02332A 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]:44432 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L2V-0007IU-LY for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:28:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42127) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0N-0004VA-Gh for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0K-0007zx-Sg for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:03 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:52929) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0J-0007t8-JY; Wed, 21 Aug 2019 03:26:00 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46Czj92zX7z9sPT; Wed, 21 Aug 2019 17:25:49 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372349; bh=ohKNLMSxUBTSloSSXh5QWUdJQ1d0K/JDfmjK00RiYck=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OYOQUEnt39mTtKfYl72XHPmrAZpx0rVq5F3tkxeqDn4dZgeIO/NtWESNFs5ujD9kC dkNQYngAEW6MUBLFioFKdJrB4X86u4PTAsilBhlhFqPk1RFzPrNbAMjpcmFQuarfJu nRaP63Z/q4Zxrml7Xx5ZGeTGfbhJ3Z8eQtn4Y2vQ= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:09 +1000 Message-Id: <20190821072542.23090-10-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 09/42] target/ppc: Optimize emulation of vgbbd instruction 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, aik@ozlabs.ru, Richard Henderson , qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, Stefan Brankovic , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Stefan Brankovic Optimize altivec instruction vgbbd (Vector Gather Bits by Bytes by Doubleword) All ith bits (i in range 1 to 8) of each byte of doubleword element in source register are concatenated and placed into ith byte of appropriate doubleword element in destination register. Following solution is done for both doubleword elements of source register in parallel, in order to reduce the number of instructions needed(that's why arrays are used): First, both doubleword elements of source register vB are placed in appropriate element of array avr. Bits are gathered in 2x8 iterations(2 for loops). In first iteration bit 1 of byte 1, bit 2 of byte 2,... bit 8 of byte 8 are in their final spots so avr[i], i={0,1} can be and-ed with tcg_mask. For every following iteration, both avr[i] and tcg_mask variables have to be shifted right for 7 and 8 places, respectively, in order to get bit 1 of byte 2, bit 2 of byte 3.. bit 7 of byte 8 in their final spots so shifted avr values(saved in tmp) can be and-ed with new value of tcg_mask... After first 8 iteration(first loop), all the first bits are in their final places, all second bits but second bit from eight byte are in their places... only 1 eight bit from eight byte is in it's place). In second loop we do all operations symmetrically, in order to get other half of bits in their final spots. Results for first and second doubleword elements are saved in result[0] and result[1] respectively. In the end those results are saved in appropriate doubleword element of destination register vD. Signed-off-by: Stefan Brankovic Reviewed-by: Richard Henderson Message-Id: <1563200574-11098-5-git-send-email-stefan.brankovic@rt-rk.com> Signed-off-by: David Gibson --- target/ppc/helper.h | 1 - target/ppc/int_helper.c | 276 ---------------------------- target/ppc/translate/vmx-impl.inc.c | 77 +++++++- 3 files changed, 76 insertions(+), 278 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 6fb823c7b4..9b486a0c37 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -324,7 +324,6 @@ DEF_HELPER_1(vclzlsbb, tl, avr) DEF_HELPER_1(vctzlsbb, tl, avr) DEF_HELPER_3(vbpermd, void, avr, avr, avr) DEF_HELPER_3(vbpermq, void, avr, avr, avr) -DEF_HELPER_2(vgbbd, void, avr, avr) DEF_HELPER_3(vpmsumb, void, avr, avr, avr) DEF_HELPER_3(vpmsumh, void, avr, avr, avr) DEF_HELPER_3(vpmsumw, void, avr, avr, avr) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index d2cad787ad..a265cb07c5 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -1187,282 +1187,6 @@ void helper_vbpermq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) #undef VBPERMQ_INDEX #undef VBPERMQ_DW -static const uint64_t VGBBD_MASKS[256] = { - 0x0000000000000000ull, /* 00 */ - 0x0000000000000080ull, /* 01 */ - 0x0000000000008000ull, /* 02 */ - 0x0000000000008080ull, /* 03 */ - 0x0000000000800000ull, /* 04 */ - 0x0000000000800080ull, /* 05 */ - 0x0000000000808000ull, /* 06 */ - 0x0000000000808080ull, /* 07 */ - 0x0000000080000000ull, /* 08 */ - 0x0000000080000080ull, /* 09 */ - 0x0000000080008000ull, /* 0A */ - 0x0000000080008080ull, /* 0B */ - 0x0000000080800000ull, /* 0C */ - 0x0000000080800080ull, /* 0D */ - 0x0000000080808000ull, /* 0E */ - 0x0000000080808080ull, /* 0F */ - 0x0000008000000000ull, /* 10 */ - 0x0000008000000080ull, /* 11 */ - 0x0000008000008000ull, /* 12 */ - 0x0000008000008080ull, /* 13 */ - 0x0000008000800000ull, /* 14 */ - 0x0000008000800080ull, /* 15 */ - 0x0000008000808000ull, /* 16 */ - 0x0000008000808080ull, /* 17 */ - 0x0000008080000000ull, /* 18 */ - 0x0000008080000080ull, /* 19 */ - 0x0000008080008000ull, /* 1A */ - 0x0000008080008080ull, /* 1B */ - 0x0000008080800000ull, /* 1C */ - 0x0000008080800080ull, /* 1D */ - 0x0000008080808000ull, /* 1E */ - 0x0000008080808080ull, /* 1F */ - 0x0000800000000000ull, /* 20 */ - 0x0000800000000080ull, /* 21 */ - 0x0000800000008000ull, /* 22 */ - 0x0000800000008080ull, /* 23 */ - 0x0000800000800000ull, /* 24 */ - 0x0000800000800080ull, /* 25 */ - 0x0000800000808000ull, /* 26 */ - 0x0000800000808080ull, /* 27 */ - 0x0000800080000000ull, /* 28 */ - 0x0000800080000080ull, /* 29 */ - 0x0000800080008000ull, /* 2A */ - 0x0000800080008080ull, /* 2B */ - 0x0000800080800000ull, /* 2C */ - 0x0000800080800080ull, /* 2D */ - 0x0000800080808000ull, /* 2E */ - 0x0000800080808080ull, /* 2F */ - 0x0000808000000000ull, /* 30 */ - 0x0000808000000080ull, /* 31 */ - 0x0000808000008000ull, /* 32 */ - 0x0000808000008080ull, /* 33 */ - 0x0000808000800000ull, /* 34 */ - 0x0000808000800080ull, /* 35 */ - 0x0000808000808000ull, /* 36 */ - 0x0000808000808080ull, /* 37 */ - 0x0000808080000000ull, /* 38 */ - 0x0000808080000080ull, /* 39 */ - 0x0000808080008000ull, /* 3A */ - 0x0000808080008080ull, /* 3B */ - 0x0000808080800000ull, /* 3C */ - 0x0000808080800080ull, /* 3D */ - 0x0000808080808000ull, /* 3E */ - 0x0000808080808080ull, /* 3F */ - 0x0080000000000000ull, /* 40 */ - 0x0080000000000080ull, /* 41 */ - 0x0080000000008000ull, /* 42 */ - 0x0080000000008080ull, /* 43 */ - 0x0080000000800000ull, /* 44 */ - 0x0080000000800080ull, /* 45 */ - 0x0080000000808000ull, /* 46 */ - 0x0080000000808080ull, /* 47 */ - 0x0080000080000000ull, /* 48 */ - 0x0080000080000080ull, /* 49 */ - 0x0080000080008000ull, /* 4A */ - 0x0080000080008080ull, /* 4B */ - 0x0080000080800000ull, /* 4C */ - 0x0080000080800080ull, /* 4D */ - 0x0080000080808000ull, /* 4E */ - 0x0080000080808080ull, /* 4F */ - 0x0080008000000000ull, /* 50 */ - 0x0080008000000080ull, /* 51 */ - 0x0080008000008000ull, /* 52 */ - 0x0080008000008080ull, /* 53 */ - 0x0080008000800000ull, /* 54 */ - 0x0080008000800080ull, /* 55 */ - 0x0080008000808000ull, /* 56 */ - 0x0080008000808080ull, /* 57 */ - 0x0080008080000000ull, /* 58 */ - 0x0080008080000080ull, /* 59 */ - 0x0080008080008000ull, /* 5A */ - 0x0080008080008080ull, /* 5B */ - 0x0080008080800000ull, /* 5C */ - 0x0080008080800080ull, /* 5D */ - 0x0080008080808000ull, /* 5E */ - 0x0080008080808080ull, /* 5F */ - 0x0080800000000000ull, /* 60 */ - 0x0080800000000080ull, /* 61 */ - 0x0080800000008000ull, /* 62 */ - 0x0080800000008080ull, /* 63 */ - 0x0080800000800000ull, /* 64 */ - 0x0080800000800080ull, /* 65 */ - 0x0080800000808000ull, /* 66 */ - 0x0080800000808080ull, /* 67 */ - 0x0080800080000000ull, /* 68 */ - 0x0080800080000080ull, /* 69 */ - 0x0080800080008000ull, /* 6A */ - 0x0080800080008080ull, /* 6B */ - 0x0080800080800000ull, /* 6C */ - 0x0080800080800080ull, /* 6D */ - 0x0080800080808000ull, /* 6E */ - 0x0080800080808080ull, /* 6F */ - 0x0080808000000000ull, /* 70 */ - 0x0080808000000080ull, /* 71 */ - 0x0080808000008000ull, /* 72 */ - 0x0080808000008080ull, /* 73 */ - 0x0080808000800000ull, /* 74 */ - 0x0080808000800080ull, /* 75 */ - 0x0080808000808000ull, /* 76 */ - 0x0080808000808080ull, /* 77 */ - 0x0080808080000000ull, /* 78 */ - 0x0080808080000080ull, /* 79 */ - 0x0080808080008000ull, /* 7A */ - 0x0080808080008080ull, /* 7B */ - 0x0080808080800000ull, /* 7C */ - 0x0080808080800080ull, /* 7D */ - 0x0080808080808000ull, /* 7E */ - 0x0080808080808080ull, /* 7F */ - 0x8000000000000000ull, /* 80 */ - 0x8000000000000080ull, /* 81 */ - 0x8000000000008000ull, /* 82 */ - 0x8000000000008080ull, /* 83 */ - 0x8000000000800000ull, /* 84 */ - 0x8000000000800080ull, /* 85 */ - 0x8000000000808000ull, /* 86 */ - 0x8000000000808080ull, /* 87 */ - 0x8000000080000000ull, /* 88 */ - 0x8000000080000080ull, /* 89 */ - 0x8000000080008000ull, /* 8A */ - 0x8000000080008080ull, /* 8B */ - 0x8000000080800000ull, /* 8C */ - 0x8000000080800080ull, /* 8D */ - 0x8000000080808000ull, /* 8E */ - 0x8000000080808080ull, /* 8F */ - 0x8000008000000000ull, /* 90 */ - 0x8000008000000080ull, /* 91 */ - 0x8000008000008000ull, /* 92 */ - 0x8000008000008080ull, /* 93 */ - 0x8000008000800000ull, /* 94 */ - 0x8000008000800080ull, /* 95 */ - 0x8000008000808000ull, /* 96 */ - 0x8000008000808080ull, /* 97 */ - 0x8000008080000000ull, /* 98 */ - 0x8000008080000080ull, /* 99 */ - 0x8000008080008000ull, /* 9A */ - 0x8000008080008080ull, /* 9B */ - 0x8000008080800000ull, /* 9C */ - 0x8000008080800080ull, /* 9D */ - 0x8000008080808000ull, /* 9E */ - 0x8000008080808080ull, /* 9F */ - 0x8000800000000000ull, /* A0 */ - 0x8000800000000080ull, /* A1 */ - 0x8000800000008000ull, /* A2 */ - 0x8000800000008080ull, /* A3 */ - 0x8000800000800000ull, /* A4 */ - 0x8000800000800080ull, /* A5 */ - 0x8000800000808000ull, /* A6 */ - 0x8000800000808080ull, /* A7 */ - 0x8000800080000000ull, /* A8 */ - 0x8000800080000080ull, /* A9 */ - 0x8000800080008000ull, /* AA */ - 0x8000800080008080ull, /* AB */ - 0x8000800080800000ull, /* AC */ - 0x8000800080800080ull, /* AD */ - 0x8000800080808000ull, /* AE */ - 0x8000800080808080ull, /* AF */ - 0x8000808000000000ull, /* B0 */ - 0x8000808000000080ull, /* B1 */ - 0x8000808000008000ull, /* B2 */ - 0x8000808000008080ull, /* B3 */ - 0x8000808000800000ull, /* B4 */ - 0x8000808000800080ull, /* B5 */ - 0x8000808000808000ull, /* B6 */ - 0x8000808000808080ull, /* B7 */ - 0x8000808080000000ull, /* B8 */ - 0x8000808080000080ull, /* B9 */ - 0x8000808080008000ull, /* BA */ - 0x8000808080008080ull, /* BB */ - 0x8000808080800000ull, /* BC */ - 0x8000808080800080ull, /* BD */ - 0x8000808080808000ull, /* BE */ - 0x8000808080808080ull, /* BF */ - 0x8080000000000000ull, /* C0 */ - 0x8080000000000080ull, /* C1 */ - 0x8080000000008000ull, /* C2 */ - 0x8080000000008080ull, /* C3 */ - 0x8080000000800000ull, /* C4 */ - 0x8080000000800080ull, /* C5 */ - 0x8080000000808000ull, /* C6 */ - 0x8080000000808080ull, /* C7 */ - 0x8080000080000000ull, /* C8 */ - 0x8080000080000080ull, /* C9 */ - 0x8080000080008000ull, /* CA */ - 0x8080000080008080ull, /* CB */ - 0x8080000080800000ull, /* CC */ - 0x8080000080800080ull, /* CD */ - 0x8080000080808000ull, /* CE */ - 0x8080000080808080ull, /* CF */ - 0x8080008000000000ull, /* D0 */ - 0x8080008000000080ull, /* D1 */ - 0x8080008000008000ull, /* D2 */ - 0x8080008000008080ull, /* D3 */ - 0x8080008000800000ull, /* D4 */ - 0x8080008000800080ull, /* D5 */ - 0x8080008000808000ull, /* D6 */ - 0x8080008000808080ull, /* D7 */ - 0x8080008080000000ull, /* D8 */ - 0x8080008080000080ull, /* D9 */ - 0x8080008080008000ull, /* DA */ - 0x8080008080008080ull, /* DB */ - 0x8080008080800000ull, /* DC */ - 0x8080008080800080ull, /* DD */ - 0x8080008080808000ull, /* DE */ - 0x8080008080808080ull, /* DF */ - 0x8080800000000000ull, /* E0 */ - 0x8080800000000080ull, /* E1 */ - 0x8080800000008000ull, /* E2 */ - 0x8080800000008080ull, /* E3 */ - 0x8080800000800000ull, /* E4 */ - 0x8080800000800080ull, /* E5 */ - 0x8080800000808000ull, /* E6 */ - 0x8080800000808080ull, /* E7 */ - 0x8080800080000000ull, /* E8 */ - 0x8080800080000080ull, /* E9 */ - 0x8080800080008000ull, /* EA */ - 0x8080800080008080ull, /* EB */ - 0x8080800080800000ull, /* EC */ - 0x8080800080800080ull, /* ED */ - 0x8080800080808000ull, /* EE */ - 0x8080800080808080ull, /* EF */ - 0x8080808000000000ull, /* F0 */ - 0x8080808000000080ull, /* F1 */ - 0x8080808000008000ull, /* F2 */ - 0x8080808000008080ull, /* F3 */ - 0x8080808000800000ull, /* F4 */ - 0x8080808000800080ull, /* F5 */ - 0x8080808000808000ull, /* F6 */ - 0x8080808000808080ull, /* F7 */ - 0x8080808080000000ull, /* F8 */ - 0x8080808080000080ull, /* F9 */ - 0x8080808080008000ull, /* FA */ - 0x8080808080008080ull, /* FB */ - 0x8080808080800000ull, /* FC */ - 0x8080808080800080ull, /* FD */ - 0x8080808080808000ull, /* FE */ - 0x8080808080808080ull, /* FF */ -}; - -void helper_vgbbd(ppc_avr_t *r, ppc_avr_t *b) -{ - int i; - uint64_t t[2] = { 0, 0 }; - - VECTOR_FOR_INORDER_I(i, u8) { -#if defined(HOST_WORDS_BIGENDIAN) - t[i >> 3] |= VGBBD_MASKS[b->u8[i]] >> (i & 7); -#else - t[i >> 3] |= VGBBD_MASKS[b->u8[i]] >> (7 - (i & 7)); -#endif - } - - r->u64[0] = t[0]; - r->u64[1] = t[1]; -} - #define PMSUM(name, srcfld, trgfld, trgtyp) \ void helper_##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \ diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index e06e65adb2..13153352e4 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -667,6 +667,81 @@ static void trans_vsr(DisasContext *ctx) tcg_temp_free_i64(tmp); } +/* + * vgbbd VRT,VRB - Vector Gather Bits by Bytes by Doubleword + * + * All ith bits (i in range 1 to 8) of each byte of doubleword element in source + * register are concatenated and placed into ith byte of appropriate doubleword + * element in destination register. + * + * Following solution is done for both doubleword elements of source register + * in parallel, in order to reduce the number of instructions needed(that's why + * arrays are used): + * First, both doubleword elements of source register vB are placed in + * appropriate element of array avr. Bits are gathered in 2x8 iterations(2 for + * loops). In first iteration bit 1 of byte 1, bit 2 of byte 2,... bit 8 of + * byte 8 are in their final spots so avr[i], i={0,1} can be and-ed with + * tcg_mask. For every following iteration, both avr[i] and tcg_mask variables + * have to be shifted right for 7 and 8 places, respectively, in order to get + * bit 1 of byte 2, bit 2 of byte 3.. bit 7 of byte 8 in their final spots so + * shifted avr values(saved in tmp) can be and-ed with new value of tcg_mask... + * After first 8 iteration(first loop), all the first bits are in their final + * places, all second bits but second bit from eight byte are in their places... + * only 1 eight bit from eight byte is in it's place). In second loop we do all + * operations symmetrically, in order to get other half of bits in their final + * spots. Results for first and second doubleword elements are saved in + * result[0] and result[1] respectively. In the end those results are saved in + * appropriate doubleword element of destination register vD. + */ +static void trans_vgbbd(DisasContext *ctx) +{ + int VT = rD(ctx->opcode); + int VB = rB(ctx->opcode); + TCGv_i64 tmp = tcg_temp_new_i64(); + uint64_t mask = 0x8040201008040201ULL; + int i, j; + + TCGv_i64 result[2]; + result[0] = tcg_temp_new_i64(); + result[1] = tcg_temp_new_i64(); + TCGv_i64 avr[2]; + avr[0] = tcg_temp_new_i64(); + avr[1] = tcg_temp_new_i64(); + TCGv_i64 tcg_mask = tcg_temp_new_i64(); + + tcg_gen_movi_i64(tcg_mask, mask); + for (j = 0; j < 2; j++) { + get_avr64(avr[j], VB, j); + tcg_gen_and_i64(result[j], avr[j], tcg_mask); + } + for (i = 1; i < 8; i++) { + tcg_gen_movi_i64(tcg_mask, mask >> (i * 8)); + for (j = 0; j < 2; j++) { + tcg_gen_shri_i64(tmp, avr[j], i * 7); + tcg_gen_and_i64(tmp, tmp, tcg_mask); + tcg_gen_or_i64(result[j], result[j], tmp); + } + } + for (i = 1; i < 8; i++) { + tcg_gen_movi_i64(tcg_mask, mask << (i * 8)); + for (j = 0; j < 2; j++) { + tcg_gen_shli_i64(tmp, avr[j], i * 7); + tcg_gen_and_i64(tmp, tmp, tcg_mask); + tcg_gen_or_i64(result[j], result[j], tmp); + } + } + for (j = 0; j < 2; j++) { + set_avr64(VT, result[j], j); + } + + tcg_temp_free_i64(tmp); + tcg_temp_free_i64(tcg_mask); + tcg_temp_free_i64(result[0]); + tcg_temp_free_i64(result[1]); + tcg_temp_free_i64(avr[0]); + tcg_temp_free_i64(avr[1]); +} + GEN_VXFORM(vmuloub, 4, 0); GEN_VXFORM(vmulouh, 4, 1); GEN_VXFORM(vmulouw, 4, 2); @@ -1211,7 +1286,7 @@ GEN_VXFORM_DUAL(vclzd, PPC_NONE, PPC2_ALTIVEC_207, \ vpopcntd, PPC_NONE, PPC2_ALTIVEC_207) GEN_VXFORM(vbpermd, 6, 23); GEN_VXFORM(vbpermq, 6, 21); -GEN_VXFORM_NOA(vgbbd, 6, 20); +GEN_VXFORM_TRANS(vgbbd, 6, 20); GEN_VXFORM(vpmsumb, 4, 16) GEN_VXFORM(vpmsumh, 4, 17) GEN_VXFORM(vpmsumw, 4, 18) From patchwork Wed Aug 21 07:25:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105787 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 4702D912 for ; Wed, 21 Aug 2019 07:32: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 1EB842332A for ; Wed, 21 Aug 2019 07:32: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="NNuX0NB6" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1EB842332A 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]:44478 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L6V-0002qF-Lf for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:32:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42080) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0M-0004TE-3Q for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0K-0007z9-Cw for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:01 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:42071) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0J-0007sy-LE; Wed, 21 Aug 2019 03:26:00 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46Czj91gHVz9sND; Wed, 21 Aug 2019 17:25:49 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372349; bh=W0SUWrowz5QUfB8a0jGTaV1ZYR7DK6nAsa+DrTnUQvc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NNuX0NB6n6B64qkQ0rMzBzAnRgxCR0trp/QjPHA7MS0CchZPSnPBJnqkqf1dHb6ht RKqtuelIJs4yhRZ9zljhaQHPJhb5F0/0u1GxVipUNnbXPMS1AGdYHmr1yUn90BE0FH pKuEXmwlgIKwCsNl9oJ6qzrl1/YGPXP9qMnAgFws= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:10 +1000 Message-Id: <20190821072542.23090-11-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 10/42] target/ppc: Optimize emulation of vclzd instruction 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, aik@ozlabs.ru, Richard Henderson , qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, Stefan Brankovic , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Stefan Brankovic Optimize Altivec instruction vclzd (Vector Count Leading Zeros Doubleword). This instruction counts the number of leading zeros of each doubleword element in source register and places result in the appropriate doubleword element of destination register. Using tcg-s count leading zeros instruction two times(once for each doubleword element of source register vB) and placing result in appropriate doubleword element of destination register vD. Signed-off-by: Stefan Brankovic Reviewed-by: Richard Henderson Message-Id: <1563200574-11098-6-git-send-email-stefan.brankovic@rt-rk.com> Signed-off-by: David Gibson --- target/ppc/helper.h | 1 - target/ppc/int_helper.c | 3 --- target/ppc/translate/vmx-impl.inc.c | 28 +++++++++++++++++++++++++++- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 9b486a0c37..e203f76bf1 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -311,7 +311,6 @@ DEF_HELPER_4(vctsxs, void, env, avr, avr, i32) DEF_HELPER_2(vclzb, void, avr, avr) DEF_HELPER_2(vclzh, void, avr, avr) DEF_HELPER_2(vclzw, void, avr, avr) -DEF_HELPER_2(vclzd, void, avr, avr) DEF_HELPER_2(vctzb, void, avr, avr) DEF_HELPER_2(vctzh, void, avr, avr) DEF_HELPER_2(vctzw, void, avr, avr) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index a265cb07c5..b82765db33 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -1820,17 +1820,14 @@ VUPK(lsw, s64, s32, UPKLO) #define clzb(v) ((v) ? clz32((uint32_t)(v) << 24) : 8) #define clzh(v) ((v) ? clz32((uint32_t)(v) << 16) : 16) #define clzw(v) clz32((v)) -#define clzd(v) clz64((v)) VGENERIC_DO(clzb, u8) VGENERIC_DO(clzh, u16) VGENERIC_DO(clzw, u32) -VGENERIC_DO(clzd, u64) #undef clzb #undef clzh #undef clzw -#undef clzd #define ctzb(v) ((v) ? ctz32(v) : 8) #define ctzh(v) ((v) ? ctz32(v) : 16) diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index 13153352e4..3372c2c3d3 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -742,6 +742,32 @@ static void trans_vgbbd(DisasContext *ctx) tcg_temp_free_i64(avr[1]); } +/* + * vclzd VRT,VRB - Vector Count Leading Zeros Doubleword + * + * Counting the number of leading zero bits of each doubleword element in source + * register and placing result in appropriate doubleword element of destination + * register. + */ +static void trans_vclzd(DisasContext *ctx) +{ + int VT = rD(ctx->opcode); + int VB = rB(ctx->opcode); + TCGv_i64 avr = tcg_temp_new_i64(); + + /* high doubleword */ + get_avr64(avr, VB, true); + tcg_gen_clzi_i64(avr, avr, 64); + set_avr64(VT, avr, true); + + /* low doubleword */ + get_avr64(avr, VB, false); + tcg_gen_clzi_i64(avr, avr, 64); + set_avr64(VT, avr, false); + + tcg_temp_free_i64(avr); +} + GEN_VXFORM(vmuloub, 4, 0); GEN_VXFORM(vmulouh, 4, 1); GEN_VXFORM(vmulouw, 4, 2); @@ -1258,7 +1284,7 @@ GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23) GEN_VXFORM_NOA(vclzb, 1, 28) GEN_VXFORM_NOA(vclzh, 1, 29) GEN_VXFORM_NOA(vclzw, 1, 30) -GEN_VXFORM_NOA(vclzd, 1, 31) +GEN_VXFORM_TRANS(vclzd, 1, 31) GEN_VXFORM_NOA_2(vnegw, 1, 24, 6) GEN_VXFORM_NOA_2(vnegd, 1, 24, 7) GEN_VXFORM_NOA_2(vextsb2w, 1, 24, 16) From patchwork Wed Aug 21 07:25:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105825 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 7C172912 for ; Wed, 21 Aug 2019 07:38:48 +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 5279E22CE3 for ; Wed, 21 Aug 2019 07:38:48 +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="C9Jw+PM+" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5279E22CE3 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]:44540 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LCg-0002Yz-Rg for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:38:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42081) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0M-0004TF-4C for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0K-0007zK-Db for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:01 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:53655) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0J-0007t6-O5; Wed, 21 Aug 2019 03:26:00 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46Czj92GJcz9sPP; Wed, 21 Aug 2019 17:25:49 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372349; bh=Man+cTJD40md8jcRo0qPDBf0tBh7Y8v0Agzqmq1Hr8A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=C9Jw+PM+zVZzvjlx2A+T3AXMLKaASEinDY7UNVoatHUOkIOaF+DiBTifb2/9ukiBi kmuiq1k7F7xHA/lovpyBEy+zlCuBMItuYBFOs8R3DXEQN79VgZ+875RqhjNgrLWvt0 ci+kGL51W05cOy/TZCw1kcvuvQEKLjO6f8Soz0oM= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:11 +1000 Message-Id: <20190821072542.23090-12-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 11/42] target/ppc: Optimize emulation of vclzw instruction 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, aik@ozlabs.ru, Richard Henderson , qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, Stefan Brankovic , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Stefan Brankovic Optimize Altivec instruction vclzw (Vector Count Leading Zeros Word). This instruction counts the number of leading zeros of each word element in source register and places result in the appropriate word element of destination register. Counting is to be performed in four iterations of for loop(one for each word elemnt of source register vB). Every iteration consists of loading appropriate word element from source register, counting leading zeros with tcg_gen_clzi_i32, and saving the result in appropriate word element of destination register. Signed-off-by: Stefan Brankovic Reviewed-by: Richard Henderson Message-Id: <1563200574-11098-7-git-send-email-stefan.brankovic@rt-rk.com> Signed-off-by: David Gibson --- target/ppc/helper.h | 1 - target/ppc/int_helper.c | 3 --- target/ppc/translate/vmx-impl.inc.c | 28 +++++++++++++++++++++++++++- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index e203f76bf1..54ea9b9500 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -310,7 +310,6 @@ DEF_HELPER_4(vctsxs, void, env, avr, avr, i32) DEF_HELPER_2(vclzb, void, avr, avr) DEF_HELPER_2(vclzh, void, avr, avr) -DEF_HELPER_2(vclzw, void, avr, avr) DEF_HELPER_2(vctzb, void, avr, avr) DEF_HELPER_2(vctzh, void, avr, avr) DEF_HELPER_2(vctzw, void, avr, avr) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index b82765db33..46deb57a34 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -1819,15 +1819,12 @@ VUPK(lsw, s64, s32, UPKLO) #define clzb(v) ((v) ? clz32((uint32_t)(v) << 24) : 8) #define clzh(v) ((v) ? clz32((uint32_t)(v) << 16) : 16) -#define clzw(v) clz32((v)) VGENERIC_DO(clzb, u8) VGENERIC_DO(clzh, u16) -VGENERIC_DO(clzw, u32) #undef clzb #undef clzh -#undef clzw #define ctzb(v) ((v) ? ctz32(v) : 8) #define ctzh(v) ((v) ? ctz32(v) : 16) diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index 3372c2c3d3..0d71c10428 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -742,6 +742,32 @@ static void trans_vgbbd(DisasContext *ctx) tcg_temp_free_i64(avr[1]); } +/* + * vclzw VRT,VRB - Vector Count Leading Zeros Word + * + * Counting the number of leading zero bits of each word element in source + * register and placing result in appropriate word element of destination + * register. + */ +static void trans_vclzw(DisasContext *ctx) +{ + int VT = rD(ctx->opcode); + int VB = rB(ctx->opcode); + TCGv_i32 tmp = tcg_temp_new_i32(); + int i; + + /* Perform count for every word element using tcg_gen_clzi_i32. */ + for (i = 0; i < 4; i++) { + tcg_gen_ld_i32(tmp, cpu_env, + offsetof(CPUPPCState, vsr[32 + VB].u64[0]) + i * 4); + tcg_gen_clzi_i32(tmp, tmp, 32); + tcg_gen_st_i32(tmp, cpu_env, + offsetof(CPUPPCState, vsr[32 + VT].u64[0]) + i * 4); + } + + tcg_temp_free_i32(tmp); +} + /* * vclzd VRT,VRB - Vector Count Leading Zeros Doubleword * @@ -1283,7 +1309,7 @@ GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23) GEN_VXFORM_NOA(vclzb, 1, 28) GEN_VXFORM_NOA(vclzh, 1, 29) -GEN_VXFORM_NOA(vclzw, 1, 30) +GEN_VXFORM_TRANS(vclzw, 1, 30) GEN_VXFORM_TRANS(vclzd, 1, 31) GEN_VXFORM_NOA_2(vnegw, 1, 24, 6) GEN_VXFORM_NOA_2(vnegd, 1, 24, 7) From patchwork Wed Aug 21 07:25:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105837 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 593251399 for ; Wed, 21 Aug 2019 07:42:47 +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 307942339F for ; Wed, 21 Aug 2019 07:42:47 +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="plNQQtbs" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 307942339F 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]:44576 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LGX-00088H-VN for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:42:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42222) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0R-0004Zw-NP for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0Q-00085q-DJ for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:07 -0400 Received: from ozlabs.org ([203.11.71.1]:38709) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0O-00080z-4o; Wed, 21 Aug 2019 03:26:06 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjC0XKZz9sPX; Wed, 21 Aug 2019 17:25:49 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372351; bh=Earpzbotodmq+6AVBesUPaAt9w4yNd1a53n3eu+jomQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=plNQQtbs17e80F8ssoB9Qzr8Qg/OUJHBSA6yQXrgzetQRV7+Og8UfBy5exddsJ80S 6IXct0XwJa3QUyYKyPxvJ4IRTsU8UFRbzEC9tGgN5CyqrcHD7qmTscTR3bSlPI5AFJ fEwtgFqLkJZawUnE1RQroasNrAdWnI8zH/5Sszbk= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:12 +1000 Message-Id: <20190821072542.23090-13-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 12/42] ppc: fix memory leak in spapr_caps_add_properties 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, Shivaprasad G Bhat , aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Shivaprasad G Bhat Free the capability name string after setting the capability. Signed-off-by: Shivaprasad G Bhat Message-Id: <156335156198.82682.8756968724044750843.stgit@lep8c.aus.stglabs.ibm.com> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr_caps.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index a61bf329bf..481dfd2a27 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -793,7 +793,7 @@ void spapr_caps_add_properties(SpaprMachineClass *smc, Error **errp) for (i = 0; i < ARRAY_SIZE(capability_table); i++) { SpaprCapabilityInfo *cap = &capability_table[i]; - const char *name = g_strdup_printf("cap-%s", cap->name); + char *name = g_strdup_printf("cap-%s", cap->name); char *desc; object_class_property_add(klass, name, cap->type, @@ -801,11 +801,13 @@ void spapr_caps_add_properties(SpaprMachineClass *smc, Error **errp) NULL, cap, &local_err); if (local_err) { error_propagate(errp, local_err); + g_free(name); return; } desc = g_strdup_printf("%s", cap->description); object_class_property_set_description(klass, name, desc, &local_err); + g_free(name); g_free(desc); if (local_err) { error_propagate(errp, local_err); From patchwork Wed Aug 21 07:25:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105853 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 946D714F7 for ; Wed, 21 Aug 2019 07:48: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 6ABD12339F for ; Wed, 21 Aug 2019 07:48: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="P0bvpi1f" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6ABD12339F 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]:44642 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LLu-000691-Sd for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:48:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42235) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0S-0004ao-1w for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0Q-000861-DB for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:07 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:54263) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0O-00080q-Ao; Wed, 21 Aug 2019 03:26:06 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjB5DLfz9sPw; Wed, 21 Aug 2019 17:25:49 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372350; bh=woew5jedMl67jP/p1INAk3eA67fBKDOdXV2P5VEctgQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=P0bvpi1fxH0WOoFMqvuSAaFOsFh1M1FUiNHrR0JatMb3uOyYRBwlSHlwmTRw8uB1o 2K/O9U7E9lkwlt8wJ98qoOQ+WNyQWXYNZm2rLpvMzuzOjEWFglX6BnTz5fzPd+T0cd ouGBnCxD1H2xuuv0MeF5rCXGQ9mg/8qIWdiDFxxE= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:13 +1000 Message-Id: <20190821072542.23090-14-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 13/42] ppc: fix memory leak in spapr_dt_drc() 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, Shivaprasad G Bhat , aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Shivaprasad G Bhat Leaking the drc_name while preparing the DT properties. Fixing that. Also, remove the const qualifier from spapr_drc_name(). Signed-off-by: Shivaprasad G Bhat Message-Id: <156335159028.82682.5404622104535818162.stgit@lep8c.aus.stglabs.ibm.com> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr_drc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 09255f4951..62f1a42592 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -227,7 +227,7 @@ static uint32_t drc_set_unusable(SpaprDrc *drc) return RTAS_OUT_SUCCESS; } -static const char *spapr_drc_name(SpaprDrc *drc) +static char *spapr_drc_name(SpaprDrc *drc) { SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); @@ -828,6 +828,7 @@ int spapr_dt_drc(void *fdt, int offset, Object *owner, uint32_t drc_type_mask) Object *obj; SpaprDrc *drc; SpaprDrcClass *drck; + char *drc_name = NULL; uint32_t drc_index, drc_power_domain; if (!strstart(prop->type, "link<", NULL)) { @@ -857,8 +858,10 @@ int spapr_dt_drc(void *fdt, int offset, Object *owner, uint32_t drc_type_mask) g_array_append_val(drc_power_domains, drc_power_domain); /* ibm,drc-names */ - drc_names = g_string_append(drc_names, spapr_drc_name(drc)); + drc_name = spapr_drc_name(drc); + drc_names = g_string_append(drc_names, drc_name); drc_names = g_string_insert_len(drc_names, -1, "\0", 1); + g_free(drc_name); /* ibm,drc-types */ drc_types = g_string_append(drc_types, drck->typename); From patchwork Wed Aug 21 07:25:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105863 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 D515F14F7 for ; Wed, 21 Aug 2019 07:51:31 +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 AD34722DA7 for ; Wed, 21 Aug 2019 07:51:31 +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="d8j2wIRU" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AD34722DA7 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]:44686 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LP0-0001Ie-Lc for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:51:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42308) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0T-0004dm-Ld for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0Q-000868-FW for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:09 -0400 Received: from ozlabs.org ([203.11.71.1]:57403) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0O-00081U-A0; Wed, 21 Aug 2019 03:26:06 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjC3WPxz9sPn; Wed, 21 Aug 2019 17:25:49 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372351; bh=/Dle6wZbIMbneQ+F1agaSsQQsfyIA7WAL1f4+JCNAao=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=d8j2wIRUJmBhNjWfYl7uoXnxf08Au1I3LH/wmEnWcUGgbvLH+6QpQrvmFmOptdeSJ P0vyDc9NEACcVmAE0hnQ0W3+ZQSIBjo5DgmLHCsCxjql+f3YjphP6IufUCUHHMkQx+ wEHFX9jLttP2NA+UhFx4oQ2Dtho5MjPwUY1sJch4= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:14 +1000 Message-Id: <20190821072542.23090-15-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 14/42] ppc: fix leak in h_client_architecture_support 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, Shivaprasad G Bhat , aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Shivaprasad G Bhat Free all SpaprOptionVector local pointers after use. Signed-off-by: Shivaprasad G Bhat Message-Id: <156335160761.82682.11912058325777251614.stgit@lep8c.aus.stglabs.ibm.com> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr_hcall.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 225c60a9fc..47b566882b 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1613,6 +1613,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu, ov5_updates = spapr_ovec_new(); spapr->cas_reboot = spapr_ovec_diff(ov5_updates, ov5_cas_old, spapr->ov5_cas); + spapr_ovec_cleanup(ov5_cas_old); /* Now that processing is finished, set the radix/hash bit for the * guest if it requested a valid mode; otherwise terminate the boot. */ if (guest_radix) { @@ -1630,6 +1631,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu, } spapr->cas_legacy_guest_workaround = !spapr_ovec_test(ov1_guest, OV1_PPC_3_00); + spapr_ovec_cleanup(ov1_guest); if (!spapr->cas_reboot) { /* If spapr_machine_reset() did not set up a HPT but one is necessary * (because the guest isn't going to use radix) then set it up here. */ From patchwork Wed Aug 21 07:25:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105829 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 CB5B1174A for ; Wed, 21 Aug 2019 07:40:12 +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 A2BAD22CE3 for ; Wed, 21 Aug 2019 07:40:12 +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="iLNllmOh" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A2BAD22CE3 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]:44546 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LE3-00040X-De for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:40:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42183) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0Q-0004XV-FP for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0O-000844-8b for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:06 -0400 Received: from ozlabs.org ([203.11.71.1]:33927) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0N-00080y-M8; Wed, 21 Aug 2019 03:26:04 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjC1N27z9sPV; Wed, 21 Aug 2019 17:25:49 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372351; bh=WXwNYOWKcVD8fT6frteigyYRh/UVz+d5FBWDZT7i9rQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iLNllmOh2zTxqOSj/iwteCxEA7jtU/kdcutl/0Oza9GpLq/FhcfiBcoBmUxPqtmJI 9WL7dRHeG+SZcQ6dv0aCgWpEv7FUCWNJzoDb9BDiIJdyy41r/CtO08zdFjaL8N0RYV hbLcqQ5NZBRZRDWfoIdPh11ThkOLeswbTYteGnM8= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:15 +1000 Message-Id: <20190821072542.23090-16-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 15/42] spapr: Implement dispatch tracking for tcg 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, aik@ozlabs.ru, qemu-devel@nongnu.org, Nicholas Piggin , groug@kaod.org, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Nicholas Piggin Implement cpu_exec_enter/exit on ppc which calls into new methods of the same name in PPCVirtualHypervisorClass. These are used by spapr to implement the splpar VPA dispatch counter initially. Signed-off-by: Nicholas Piggin Message-Id: <20190718034214.14948-2-npiggin@gmail.com> [dwg: Removed unnecessary CONFIG_USER_ONLY checks as suggested by gkurz] Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr.c | 48 +++++++++++++++++++++++++++++++++ hw/ppc/spapr_hcall.c | 5 ---- include/hw/ppc/spapr.h | 7 +++++ target/ppc/cpu.h | 4 +++ target/ppc/translate_init.inc.c | 27 +++++++++++++++++++ 5 files changed, 86 insertions(+), 5 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 22a45c3737..08cc7c2bd6 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4306,6 +4306,52 @@ PowerPCCPU *spapr_find_cpu(int vcpu_id) return NULL; } +static void spapr_cpu_exec_enter(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu) +{ + SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); + + /* These are only called by TCG, KVM maintains dispatch state */ + + if (spapr_cpu->vpa_addr) { + CPUState *cs = CPU(cpu); + uint32_t dispatch; + + dispatch = ldl_be_phys(cs->as, + spapr_cpu->vpa_addr + VPA_DISPATCH_COUNTER); + dispatch++; + if ((dispatch & 1) != 0) { + qemu_log_mask(LOG_GUEST_ERROR, + "VPA: incorrect dispatch counter value for " + "dispatched partition %u, correcting.\n", dispatch); + dispatch++; + } + stl_be_phys(cs->as, + spapr_cpu->vpa_addr + VPA_DISPATCH_COUNTER, dispatch); + } +} + +static void spapr_cpu_exec_exit(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu) +{ + SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); + + if (spapr_cpu->vpa_addr) { + CPUState *cs = CPU(cpu); + uint32_t dispatch; + + dispatch = ldl_be_phys(cs->as, + spapr_cpu->vpa_addr + VPA_DISPATCH_COUNTER); + dispatch++; + if ((dispatch & 1) != 1) { + qemu_log_mask(LOG_GUEST_ERROR, + "VPA: incorrect dispatch counter value for " + "preempted partition %u, correcting.\n", dispatch); + dispatch++; + } + stl_be_phys(cs->as, + spapr_cpu->vpa_addr + VPA_DISPATCH_COUNTER, dispatch); + } +} + static void spapr_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -4362,6 +4408,8 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) vhc->hpte_set_r = spapr_hpte_set_r; vhc->get_pate = spapr_get_pate; vhc->encode_hpt_for_kvm_pr = spapr_encode_hpt_for_kvm_pr; + vhc->cpu_exec_enter = spapr_cpu_exec_enter; + vhc->cpu_exec_exit = spapr_cpu_exec_exit; xic->ics_get = spapr_ics_get; xic->ics_resend = spapr_ics_resend; xic->icp_get = spapr_icp_get; diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 47b566882b..4c5ea17250 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -875,11 +875,6 @@ unmap_out: #define FLAGS_DEREGISTER_DTL 0x0000c00000000000ULL #define FLAGS_DEREGISTER_SLBSHADOW 0x0000e00000000000ULL -#define VPA_MIN_SIZE 640 -#define VPA_SIZE_OFFSET 0x4 -#define VPA_SHARED_PROC_OFFSET 0x9 -#define VPA_SHARED_PROC_VAL 0x2 - static target_ulong register_vpa(PowerPCCPU *cpu, target_ulong vpa) { CPUState *cs = CPU(cpu); diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 60553d32c4..5d36eec9d0 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -525,6 +525,13 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn); target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode, target_ulong *args); +/* Virtual Processor Area structure constants */ +#define VPA_MIN_SIZE 640 +#define VPA_SIZE_OFFSET 0x4 +#define VPA_SHARED_PROC_OFFSET 0x9 +#define VPA_SHARED_PROC_VAL 0x2 +#define VPA_DISPATCH_COUNTER 0x100 + /* ibm,set-eeh-option */ #define RTAS_EEH_DISABLE 0 #define RTAS_EEH_ENABLE 1 diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 630a25c246..50245a8c4d 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1224,6 +1224,10 @@ struct PPCVirtualHypervisorClass { void (*hpte_set_r)(PPCVirtualHypervisor *vhyp, hwaddr ptex, uint64_t pte1); void (*get_pate)(PPCVirtualHypervisor *vhyp, ppc_v3_pate_t *entry); target_ulong (*encode_hpt_for_kvm_pr)(PPCVirtualHypervisor *vhyp); +#ifndef CONFIG_USER_ONLY + void (*cpu_exec_enter)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu); + void (*cpu_exec_exit)(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu); +#endif }; #define TYPE_PPC_VIRTUAL_HYPERVISOR "ppc-virtual-hypervisor" diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index 9cd2033bb9..c9fcd87095 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -10469,6 +10469,28 @@ static bool ppc_cpu_is_big_endian(CPUState *cs) return !msr_le; } + +static void ppc_cpu_exec_enter(CPUState *cs) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + + if (cpu->vhyp) { + PPCVirtualHypervisorClass *vhc = + PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); + vhc->cpu_exec_enter(cpu->vhyp, cpu); + } +} + +static void ppc_cpu_exec_exit(CPUState *cs) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + + if (cpu->vhyp) { + PPCVirtualHypervisorClass *vhc = + PPC_VIRTUAL_HYPERVISOR_GET_CLASS(cpu->vhyp); + vhc->cpu_exec_exit(cpu->vhyp, cpu); + } +} #endif static void ppc_cpu_instance_init(Object *obj) @@ -10622,6 +10644,11 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data) cc->tcg_initialize = ppc_translate_init; cc->tlb_fill = ppc_cpu_tlb_fill; #endif +#ifndef CONFIG_USER_ONLY + cc->cpu_exec_enter = ppc_cpu_exec_enter; + cc->cpu_exec_exit = ppc_cpu_exec_exit; +#endif + cc->disas_set_info = ppc_disas_set_info; dc->fw_name = "PowerPC,UNKNOWN"; From patchwork Wed Aug 21 07:25:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105845 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 252471399 for ; Wed, 21 Aug 2019 07: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 F0AF02339F for ; Wed, 21 Aug 2019 07: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="azlSd8yr" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F0AF02339F 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]:44600 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LIQ-0002G4-Mv for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:44:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42223) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0R-0004Zy-R8 for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0Q-000853-8B for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:07 -0400 Received: from ozlabs.org ([203.11.71.1]:44371) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0N-0007zp-QY; Wed, 21 Aug 2019 03:26:04 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjB1GyDz9sQn; Wed, 21 Aug 2019 17:25:49 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372350; bh=+ll5cKS8GpOsg1khTBTggYL8D2mfNQnbIIz1+Y1r/oc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=azlSd8yrrBNnQcLtQ/iPF/8qkBll2P8rZUH5mD+8UVayCCFCplNMTJ6+GP8SXcE2k B8Ds2FvN+wOLCMvVwFb9SPQ+iwshZ4TzoRzoJUwZGcNP7bb+RRJ8ljaX04BT7a29Vq zubuzSg18TBzVJ6pHNFTSdhFAK2C4ySK8fkwNj6g= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:16 +1000 Message-Id: <20190821072542.23090-17-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 16/42] spapr: Implement H_PROD 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, aik@ozlabs.ru, qemu-devel@nongnu.org, Nicholas Piggin , groug@kaod.org, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Nicholas Piggin H_PROD is added, and H_CEDE is modified to test the prod bit according to PAPR. Signed-off-by: Nicholas Piggin Message-Id: <20190718034214.14948-3-npiggin@gmail.com> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr.c | 1 + hw/ppc/spapr_hcall.c | 32 ++++++++++++++++++++++++++++++++ include/hw/ppc/spapr_cpu_core.h | 1 + 3 files changed, 34 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 08cc7c2bd6..0890c2840f 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4312,6 +4312,7 @@ static void spapr_cpu_exec_enter(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu) /* These are only called by TCG, KVM maintains dispatch state */ + spapr_cpu->prod = false; if (spapr_cpu->vpa_addr) { CPUState *cs = CPU(cpu); uint32_t dispatch; diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 4c5ea17250..dd584da1ce 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1051,14 +1051,44 @@ static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr, { CPUPPCState *env = &cpu->env; CPUState *cs = CPU(cpu); + SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); env->msr |= (1ULL << MSR_EE); hreg_compute_hflags(env); + + if (spapr_cpu->prod) { + spapr_cpu->prod = false; + return H_SUCCESS; + } + if (!cpu_has_work(cs)) { cs->halted = 1; cs->exception_index = EXCP_HLT; cs->exit_request = 1; } + + return H_SUCCESS; +} + +static target_ulong h_prod(PowerPCCPU *cpu, SpaprMachineState *spapr, + target_ulong opcode, target_ulong *args) +{ + target_long target = args[0]; + PowerPCCPU *tcpu; + CPUState *cs; + SpaprCpuState *spapr_cpu; + + tcpu = spapr_find_cpu(target); + cs = CPU(tcpu); + if (!cs) { + return H_PARAMETER; + } + + spapr_cpu = spapr_cpu_state(tcpu); + spapr_cpu->prod = true; + cs->halted = 0; + qemu_cpu_kick(cs); + return H_SUCCESS; } @@ -1885,6 +1915,8 @@ static void hypercall_register_types(void) /* hcall-splpar */ spapr_register_hypercall(H_REGISTER_VPA, h_register_vpa); spapr_register_hypercall(H_CEDE, h_cede); + spapr_register_hypercall(H_PROD, h_prod); + spapr_register_hypercall(H_SIGNAL_SYS_RESET, h_signal_sys_reset); /* processor register resource access h-calls */ diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_core.h index 35e0a7eead..1c4cc6559c 100644 --- a/include/hw/ppc/spapr_cpu_core.h +++ b/include/hw/ppc/spapr_cpu_core.h @@ -46,6 +46,7 @@ typedef struct SpaprCpuState { uint64_t vpa_addr; uint64_t slb_shadow_addr, slb_shadow_size; uint64_t dtl_addr, dtl_size; + bool prod; /* not migrated, only used to improve dispatch latencies */ struct ICPState *icp; struct XiveTCTX *tctx; } SpaprCpuState; From patchwork Wed Aug 21 07:25:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105859 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 C389613A4 for ; Wed, 21 Aug 2019 07:50: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 9A8CF22DA7 for ; Wed, 21 Aug 2019 07:50: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="M1bKnGDy" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9A8CF22DA7 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]:44660 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LNu-00080u-DP for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:50:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42309) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0T-0004dq-N1 for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0Q-00086w-U4 for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:09 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:59369) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0Q-00081Q-78; Wed, 21 Aug 2019 03:26:06 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjC20zmz9sPf; Wed, 21 Aug 2019 17:25:49 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372351; bh=QfB+kr+J9gga2TVJShNfEu3si0XX4vHShF0UZf74fkI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=M1bKnGDyMcdPGPCOrCGedYhR44GeY33QT8IaqBPm345KfB7zhbv45tmfy8aYtj0ei nuoUiUt3nRU+snPjcKTbGTGkcpjPw8S5CgQhwxPdZ8qbfzlNElb7Mw1jWUeHuhB8D+ llCJyQ6fFcpycsUef9UZ21RW9m4V52tXraWPiDkI= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:17 +1000 Message-Id: <20190821072542.23090-18-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 17/42] spapr: Implement H_CONFER 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, aik@ozlabs.ru, qemu-devel@nongnu.org, Nicholas Piggin , groug@kaod.org, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Nicholas Piggin This does not do directed yielding and is not quite as strict as PAPR specifies in terms of precise dispatch behaviour. This generally will mean suboptimal performance, rather than guest misbehaviour. Linux does not rely on exact dispatch behaviour. Signed-off-by: Nicholas Piggin Message-Id: <20190718034214.14948-4-npiggin@gmail.com> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr_hcall.c | 67 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index dd584da1ce..eb54b96097 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1070,6 +1070,72 @@ static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr, return H_SUCCESS; } +static target_ulong h_confer(PowerPCCPU *cpu, SpaprMachineState *spapr, + target_ulong opcode, target_ulong *args) +{ + target_long target = args[0]; + uint32_t dispatch = args[1]; + CPUState *cs = CPU(cpu); + SpaprCpuState *spapr_cpu; + + /* + * -1 means confer to all other CPUs without dispatch counter check, + * otherwise it's a targeted confer. + */ + if (target != -1) { + PowerPCCPU *target_cpu = spapr_find_cpu(target); + uint32_t target_dispatch; + + if (!target_cpu) { + return H_PARAMETER; + } + + spapr_cpu = spapr_cpu_state(target_cpu); + + /* + * target == self is a special case, we wait until prodded, without + * dispatch counter check. + */ + if (cpu == target_cpu) { + if (spapr_cpu->prod) { + spapr_cpu->prod = false; + + return H_SUCCESS; + } + + cs->halted = 1; + cs->exception_index = EXCP_HALTED; + cs->exit_request = 1; + + return H_SUCCESS; + } + + if (!spapr_cpu->vpa_addr || ((dispatch & 1) == 0)) { + return H_SUCCESS; + } + + target_dispatch = ldl_be_phys(cs->as, + spapr_cpu->vpa_addr + VPA_DISPATCH_COUNTER); + if (target_dispatch != dispatch) { + return H_SUCCESS; + } + + /* + * The targeted confer does not do anything special beyond yielding + * the current vCPU, but even this should be better than nothing. + * At least for single-threaded tcg, it gives the target a chance to + * run before we run again. Multi-threaded tcg does not really do + * anything with EXCP_YIELD yet. + */ + } + + cs->exception_index = EXCP_YIELD; + cs->exit_request = 1; + cpu_loop_exit(cs); + + return H_SUCCESS; +} + static target_ulong h_prod(PowerPCCPU *cpu, SpaprMachineState *spapr, target_ulong opcode, target_ulong *args) { @@ -1915,6 +1981,7 @@ static void hypercall_register_types(void) /* hcall-splpar */ spapr_register_hypercall(H_REGISTER_VPA, h_register_vpa); spapr_register_hypercall(H_CEDE, h_cede); + spapr_register_hypercall(H_CONFER, h_confer); spapr_register_hypercall(H_PROD, h_prod); spapr_register_hypercall(H_SIGNAL_SYS_RESET, h_signal_sys_reset); From patchwork Wed Aug 21 07:25:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105847 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 0CBC4174A for ; Wed, 21 Aug 2019 07:45:50 +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 D817F2339F for ; Wed, 21 Aug 2019 07:45:49 +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="YwbM8ldt" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D817F2339F 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]:44622 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LJU-0003Ow-QS for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:45:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42242) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0S-0004bg-9R for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0Q-00085w-Cf for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:08 -0400 Received: from ozlabs.org ([203.11.71.1]:58795) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0O-0007zt-6t; Wed, 21 Aug 2019 03:26:06 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjB43Fvz9sQq; Wed, 21 Aug 2019 17:25:49 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372350; bh=SfKVXl6Z5YWnWJb4dab18JG/Iivu1pPKm0+aPJywsPA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YwbM8ldtKNFkE9ebWTXUtjOuokb/mib1l/+4OJXgjfvpMx0v6HhIfox/1XEkatarE f/f0mQC19y5vr5QeI77HNvLzzJHb4OJe2U9JR5dhZ8+qOGlsb13c5kdMIL9sRfcBND bzN9y5E9zhxGDVB3k7m2K7mYHaQROupkLqAakG4A= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:18 +1000 Message-Id: <20190821072542.23090-19-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 18/42] spapr: Implement H_JOIN 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, aik@ozlabs.ru, qemu-devel@nongnu.org, Nicholas Piggin , groug@kaod.org, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Nicholas Piggin This has been useful to modify and test the Linux pseries suspend code but it requires modification to the guest to call it (due to being gated by other unimplemented features). It is not otherwise used by Linux yet, but work is slowly progressing there. Signed-off-by: Nicholas Piggin Message-Id: <20190718034214.14948-5-npiggin@gmail.com> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr.c | 1 + hw/ppc/spapr_hcall.c | 74 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 62 insertions(+), 13 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 0890c2840f..15e27d9a10 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1070,6 +1070,7 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt) add_str(hypertas, "hcall-tce"); add_str(hypertas, "hcall-vio"); add_str(hypertas, "hcall-splpar"); + add_str(hypertas, "hcall-join"); add_str(hypertas, "hcall-bulk"); add_str(hypertas, "hcall-set-mode"); add_str(hypertas, "hcall-sprg0"); diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index eb54b96097..10c0b53339 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1070,6 +1070,62 @@ static target_ulong h_cede(PowerPCCPU *cpu, SpaprMachineState *spapr, return H_SUCCESS; } +/* + * Confer to self, aka join. Cede could use the same pattern as well, if + * EXCP_HLT can be changed to ECXP_HALTED. + */ +static target_ulong h_confer_self(PowerPCCPU *cpu) +{ + CPUState *cs = CPU(cpu); + SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); + + if (spapr_cpu->prod) { + spapr_cpu->prod = false; + return H_SUCCESS; + } + cs->halted = 1; + cs->exception_index = EXCP_HALTED; + cs->exit_request = 1; + + return H_SUCCESS; +} + +static target_ulong h_join(PowerPCCPU *cpu, SpaprMachineState *spapr, + target_ulong opcode, target_ulong *args) +{ + CPUPPCState *env = &cpu->env; + CPUState *cs; + bool last_unjoined = true; + + if (env->msr & (1ULL << MSR_EE)) { + return H_BAD_MODE; + } + + /* + * Must not join the last CPU running. Interestingly, no such restriction + * for H_CONFER-to-self, but that is probably not intended to be used + * when H_JOIN is available. + */ + CPU_FOREACH(cs) { + PowerPCCPU *c = POWERPC_CPU(cs); + CPUPPCState *e = &c->env; + if (c == cpu) { + continue; + } + + /* Don't have a way to indicate joined, so use halted && MSR[EE]=0 */ + if (!cs->halted || (e->msr & (1ULL << MSR_EE))) { + last_unjoined = false; + break; + } + } + if (last_unjoined) { + return H_CONTINUE; + } + + return h_confer_self(cpu); +} + static target_ulong h_confer(PowerPCCPU *cpu, SpaprMachineState *spapr, target_ulong opcode, target_ulong *args) { @@ -1090,26 +1146,15 @@ static target_ulong h_confer(PowerPCCPU *cpu, SpaprMachineState *spapr, return H_PARAMETER; } - spapr_cpu = spapr_cpu_state(target_cpu); - /* * target == self is a special case, we wait until prodded, without * dispatch counter check. */ if (cpu == target_cpu) { - if (spapr_cpu->prod) { - spapr_cpu->prod = false; - - return H_SUCCESS; - } - - cs->halted = 1; - cs->exception_index = EXCP_HALTED; - cs->exit_request = 1; - - return H_SUCCESS; + return h_confer_self(cpu); } + spapr_cpu = spapr_cpu_state(target_cpu); if (!spapr_cpu->vpa_addr || ((dispatch & 1) == 0)) { return H_SUCCESS; } @@ -1984,6 +2029,9 @@ static void hypercall_register_types(void) spapr_register_hypercall(H_CONFER, h_confer); spapr_register_hypercall(H_PROD, h_prod); + /* hcall-join */ + spapr_register_hypercall(H_JOIN, h_join); + spapr_register_hypercall(H_SIGNAL_SYS_RESET, h_signal_sys_reset); /* processor register resource access h-calls */ From patchwork Wed Aug 21 07:25:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105819 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 4EF641399 for ; Wed, 21 Aug 2019 07:36:49 +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 264A123427 for ; Wed, 21 Aug 2019 07:36:49 +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="oEpLNhgD" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 264A123427 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]:44502 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LAl-0007jg-W2 for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:36:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42106) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0M-0004UM-UR for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0L-00080c-5i for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:02 -0400 Received: from ozlabs.org ([203.11.71.1]:60027) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0K-0007v7-Hq; Wed, 21 Aug 2019 03:26:01 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46Czj96Bmbz9sNy; Wed, 21 Aug 2019 17:25:49 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372349; bh=0dWKqVmlK2exHuzprTgcVoL1/9FViLIL4ZD9+4OJrYI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oEpLNhgDSZdutOA95xMilbrgfWcbi/HzsGw06oEWoZ06uMRKI5heKGuo5eWv57+CX wVe0cZ+mxRxzQodRmmDaW2aJOxLbi0s8A+fbAIXruydRbSJwjOvylqd4or2eFXKeXz pV07tl4UenkwVoS4I4MDL9eVNKCxPGK8FboxH3M0= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:19 +1000 Message-Id: <20190821072542.23090-20-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 19/42] docs/specs: initial spec summary for Ultravisor-related hcalls 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, aik@ozlabs.ru, Michael Roth , qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Michael Roth For now this only covers hcalls relating to TPM communication since it's the only one particularly important from a QEMU perspective atm, but others can be added here where it makes sense. The full specification for all hcalls/ucalls will eventually be made available in the public/OpenPower version of the PAPR specification. Signed-off-by: Michael Roth Message-Id: <20190717205842.17827-2-mdroth@linux.vnet.ibm.com> Signed-off-by: David Gibson --- docs/specs/ppc-spapr-uv-hcalls.txt | 76 ++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 docs/specs/ppc-spapr-uv-hcalls.txt diff --git a/docs/specs/ppc-spapr-uv-hcalls.txt b/docs/specs/ppc-spapr-uv-hcalls.txt new file mode 100644 index 0000000000..389c2740d7 --- /dev/null +++ b/docs/specs/ppc-spapr-uv-hcalls.txt @@ -0,0 +1,76 @@ +On PPC64 systems supporting Protected Execution Facility (PEF), system +memory can be placed in a secured region where only an "ultravisor" +running in firmware can provide to access it. pseries guests on such +systems can communicate with the ultravisor (via ultracalls) to switch to a +secure VM mode (SVM) where the guest's memory is relocated to this secured +region, making its memory inaccessible to normal processes/guests running on +the host. + +The various ultracalls/hypercalls relating to SVM mode are currently +only documented internally, but are planned for direct inclusion into the +public OpenPOWER version of the PAPR specification (LoPAPR/LoPAR). An internal +ACR has been filed to reserve a hypercall number range specific to this +use-case to avoid any future conflicts with the internally-maintained PAPR +specification. This document summarizes some of these details as they relate +to QEMU. + +== hypercalls needed by the ultravisor == + +Switching to SVM mode involves a number of hcalls issued by the ultravisor +to the hypervisor to orchestrate the movement of guest memory to secure +memory and various other aspects SVM mode. Numbers are assigned for these +hcalls within the reserved range 0xEF00-0xEF80. The below documents the +hcalls relevant to QEMU. + +- H_TPM_COMM (0xef10) + + For TPM_COMM_OP_EXECUTE operation: + Send a request to a TPM and receive a response, opening a new TPM session + if one has not already been opened. + + For TPM_COMM_OP_CLOSE_SESSION operation: + Close the existing TPM session, if any. + + Arguments: + + r3 : H_TPM_COMM (0xef10) + r4 : TPM operation, one of: + TPM_COMM_OP_EXECUTE (0x1) + TPM_COMM_OP_CLOSE_SESSION (0x2) + r5 : in_buffer, guest physical address of buffer containing the request + - Caller may use the same address for both request and response + r6 : in_size, size of the in buffer + - Must be less than or equal to 4KB + r7 : out_buffer, guest physical address of buffer to store the response + - Caller may use the same address for both request and response + r8 : out_size, size of the out buffer + - Must be at least 4KB, as this is the maximum request/response size + supported by most TPM implementations, including the TPM Resource + Manager in the linux kernel. + + Return values: + + r3 : H_Success request processed successfully + H_PARAMETER invalid TPM operation + H_P2 in_buffer is invalid + H_P3 in_size is invalid + H_P4 out_buffer is invalid + H_P5 out_size is invalid + H_RESOURCE problem communicating with TPM + H_FUNCTION TPM access is not currently allowed/configured + r4 : For TPM_COMM_OP_EXECUTE, the size of the response will be stored here + upon success. + + Use-case/notes: + + SVM filesystems are encrypted using a symmetric key. This key is then + wrapped/encrypted using the public key of a trusted system which has the + private key stored in the system's TPM. An Ultravisor will use this + hcall to unwrap/unseal the symmetric key using the system's TPM device + or a TPM Resource Manager associated with the device. + + The Ultravisor sets up a separate session key with the TPM in advance + during host system boot. All sensitive in and out values will be + encrypted using the session key. Though the hypervisor will see the 'in' + and 'out' buffers in raw form, any sensitive contents will generally be + encrypted using this session key. From patchwork Wed Aug 21 07:25:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105869 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 5BC3313A4 for ; Wed, 21 Aug 2019 07:54:03 +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 204C222D6D for ; Wed, 21 Aug 2019 07:54:03 +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="DcWHGsKj" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 204C222D6D 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]:44722 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LRS-0004yi-4M for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:54:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42405) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0W-0004iM-99 for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0Q-00086A-FH for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:12 -0400 Received: from ozlabs.org ([203.11.71.1]:47681) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0N-0007zs-V2; Wed, 21 Aug 2019 03:26:06 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjB31NDz9sPl; Wed, 21 Aug 2019 17:25:49 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372350; bh=9a/metOirRTSEG7Tq4eDH9MEvXMq72NnVDMTpJfr3BI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DcWHGsKjJc/lDXjYOpr54WwVvnZriG9ftM6aZ3LPwtOKr6VRqxqoEQUqz9/Vn6owr mIbh99nnkof25lUJo3Om1HkJjLR8IhF+cfsONmuiuUDoIMsTz0etk0z6GjasdUu046 CJ92VP8CtsTKnKteqXT1NCCu09+tSuseKqIGf2Io= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:20 +1000 Message-Id: <20190821072542.23090-21-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 20/42] spapr: initial implementation for H_TPM_COMM/spapr-tpm-proxy 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, aik@ozlabs.ru, Michael Roth , qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Michael Roth This implements the H_TPM_COMM hypercall, which is used by an Ultravisor to pass TPM commands directly to the host's TPM device, or a TPM Resource Manager associated with the device. This also introduces a new virtual device, spapr-tpm-proxy, which is used to configure the host TPM path to be used to service requests sent by H_TPM_COMM hcalls, for example: -device spapr-tpm-proxy,id=tpmp0,host-path=/dev/tpmrm0 By default, no spapr-tpm-proxy will be created, and hcalls will return H_FUNCTION. The full specification for this hypercall can be found in docs/specs/ppc-spapr-uv-hcalls.txt Since SVM-related hcalls like H_TPM_COMM use a reserved range of 0xEF00-0xEF80, we introduce a separate hcall table here to handle them. Signed-off-by: Michael Roth [dwg: Corrected #include for upstream change] Signed-off-by: David Gibson --- hw/ppc/Makefile.objs | 1 + hw/ppc/spapr.c | 33 +++++- hw/ppc/spapr_hcall.c | 13 +++ hw/ppc/spapr_tpm_proxy.c | 178 +++++++++++++++++++++++++++++++ hw/ppc/trace-events | 4 + include/hw/ppc/spapr.h | 11 ++ include/hw/ppc/spapr_tpm_proxy.h | 31 ++++++ 7 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 hw/ppc/spapr_tpm_proxy.c create mode 100644 include/hw/ppc/spapr_tpm_proxy.h diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs index 9da93af905..2c4e1c8de0 100644 --- a/hw/ppc/Makefile.objs +++ b/hw/ppc/Makefile.objs @@ -5,6 +5,7 @@ obj-$(CONFIG_PSERIES) += spapr.o spapr_caps.o spapr_vio.o spapr_events.o obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o obj-$(CONFIG_PSERIES) += spapr_cpu_core.o spapr_ovec.o spapr_irq.o +obj-$(CONFIG_PSERIES) += spapr_tpm_proxy.o obj-$(CONFIG_SPAPR_RNG) += spapr_rng.o # IBM PowerNV obj-$(CONFIG_POWERNV) += pnv.o pnv_xscom.o pnv_core.o pnv_lpc.o pnv_psi.o pnv_occ.o pnv_bmc.o diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 15e27d9a10..56b33571c5 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -79,6 +79,7 @@ #include "qemu/cutils.h" #include "hw/ppc/spapr_cpu_core.h" #include "hw/mem/memory-device.h" +#include "hw/ppc/spapr_tpm_proxy.h" #include @@ -4036,6 +4037,29 @@ static void spapr_phb_unplug_request(HotplugHandler *hotplug_dev, } } +static void spapr_tpm_proxy_plug(HotplugHandler *hotplug_dev, DeviceState *dev, + Error **errp) +{ + SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev)); + SpaprTpmProxy *tpm_proxy = SPAPR_TPM_PROXY(dev); + + if (spapr->tpm_proxy != NULL) { + error_setg(errp, "Only one TPM proxy can be specified for this machine"); + return; + } + + spapr->tpm_proxy = tpm_proxy; +} + +static void spapr_tpm_proxy_unplug(HotplugHandler *hotplug_dev, DeviceState *dev) +{ + SpaprMachineState *spapr = SPAPR_MACHINE(OBJECT(hotplug_dev)); + + object_property_set_bool(OBJECT(dev), false, "realized", NULL); + object_unparent(OBJECT(dev)); + spapr->tpm_proxy = NULL; +} + static void spapr_machine_device_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { @@ -4045,6 +4069,8 @@ static void spapr_machine_device_plug(HotplugHandler *hotplug_dev, spapr_core_plug(hotplug_dev, dev, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) { spapr_phb_plug(hotplug_dev, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_TPM_PROXY)) { + spapr_tpm_proxy_plug(hotplug_dev, dev, errp); } } @@ -4057,6 +4083,8 @@ static void spapr_machine_device_unplug(HotplugHandler *hotplug_dev, spapr_core_unplug(hotplug_dev, dev); } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) { spapr_phb_unplug(hotplug_dev, dev); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_TPM_PROXY)) { + spapr_tpm_proxy_unplug(hotplug_dev, dev); } } @@ -4091,6 +4119,8 @@ static void spapr_machine_device_unplug_request(HotplugHandler *hotplug_dev, return; } spapr_phb_unplug_request(hotplug_dev, dev, errp); + } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_TPM_PROXY)) { + spapr_tpm_proxy_unplug(hotplug_dev, dev); } } @@ -4111,7 +4141,8 @@ static HotplugHandler *spapr_get_hotplug_handler(MachineState *machine, { if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) || object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE) || - object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE)) { + object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_PCI_HOST_BRIDGE) || + object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_TPM_PROXY)) { return HOTPLUG_HANDLER(machine); } if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) { diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 10c0b53339..e20a946b99 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1963,6 +1963,7 @@ static target_ulong h_update_dt(PowerPCCPU *cpu, SpaprMachineState *spapr, static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1]; static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - KVMPPC_HCALL_BASE + 1]; +static spapr_hcall_fn svm_hypercall_table[(SVM_HCALL_MAX - SVM_HCALL_BASE) / 4 + 1]; void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn) { @@ -1972,6 +1973,11 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn) assert((opcode & 0x3) == 0); slot = &papr_hypercall_table[opcode / 4]; + } else if (opcode >= SVM_HCALL_BASE && opcode <= SVM_HCALL_MAX) { + /* we only have SVM-related hcall numbers assigned in multiples of 4 */ + assert((opcode & 0x3) == 0); + + slot = &svm_hypercall_table[(opcode - SVM_HCALL_BASE) / 4]; } else { assert((opcode >= KVMPPC_HCALL_BASE) && (opcode <= KVMPPC_HCALL_MAX)); @@ -1991,6 +1997,13 @@ target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode, && ((opcode & 0x3) == 0)) { spapr_hcall_fn fn = papr_hypercall_table[opcode / 4]; + if (fn) { + return fn(cpu, spapr, opcode, args); + } + } else if ((opcode >= SVM_HCALL_BASE) && + (opcode <= SVM_HCALL_MAX)) { + spapr_hcall_fn fn = svm_hypercall_table[(opcode - SVM_HCALL_BASE) / 4]; + if (fn) { return fn(cpu, spapr, opcode, args); } diff --git a/hw/ppc/spapr_tpm_proxy.c b/hw/ppc/spapr_tpm_proxy.c new file mode 100644 index 0000000000..b835d25be6 --- /dev/null +++ b/hw/ppc/spapr_tpm_proxy.c @@ -0,0 +1,178 @@ +/* + * SPAPR TPM Proxy/Hypercall + * + * Copyright IBM Corp. 2019 + * + * Authors: + * Michael Roth + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "qapi/error.h" +#include "qemu/error-report.h" +#include "sysemu/reset.h" +#include "cpu.h" +#include "hw/ppc/spapr.h" +#include "hw/qdev-properties.h" +#include "trace.h" + +#define TPM_SPAPR_BUFSIZE 4096 + +enum { + TPM_COMM_OP_EXECUTE = 1, + TPM_COMM_OP_CLOSE_SESSION = 2, +}; + +static void spapr_tpm_proxy_reset(void *opaque) +{ + SpaprTpmProxy *tpm_proxy = SPAPR_TPM_PROXY(opaque); + + if (tpm_proxy->host_fd != -1) { + close(tpm_proxy->host_fd); + tpm_proxy->host_fd = -1; + } +} + +static ssize_t tpm_execute(SpaprTpmProxy *tpm_proxy, target_ulong *args) +{ + uint64_t data_in = ppc64_phys_to_real(args[1]); + target_ulong data_in_size = args[2]; + uint64_t data_out = ppc64_phys_to_real(args[3]); + target_ulong data_out_size = args[4]; + uint8_t buf_in[TPM_SPAPR_BUFSIZE]; + uint8_t buf_out[TPM_SPAPR_BUFSIZE]; + ssize_t ret; + + trace_spapr_tpm_execute(data_in, data_in_size, data_out, data_out_size); + + if (data_in_size > TPM_SPAPR_BUFSIZE) { + error_report("invalid TPM input buffer size: " TARGET_FMT_lu, + data_in_size); + return H_P3; + } + + if (data_out_size < TPM_SPAPR_BUFSIZE) { + error_report("invalid TPM output buffer size: " TARGET_FMT_lu, + data_out_size); + return H_P5; + } + + if (tpm_proxy->host_fd == -1) { + tpm_proxy->host_fd = open(tpm_proxy->host_path, O_RDWR); + if (tpm_proxy->host_fd == -1) { + error_report("failed to open TPM device %s: %d", + tpm_proxy->host_path, errno); + return H_RESOURCE; + } + } + + cpu_physical_memory_read(data_in, buf_in, data_in_size); + + do { + ret = write(tpm_proxy->host_fd, buf_in, data_in_size); + if (ret > 0) { + data_in_size -= ret; + } + } while ((ret >= 0 && data_in_size > 0) || (ret == -1 && errno == EINTR)); + + if (ret == -1) { + error_report("failed to write to TPM device %s: %d", + tpm_proxy->host_path, errno); + return H_RESOURCE; + } + + do { + ret = read(tpm_proxy->host_fd, buf_out, data_out_size); + } while (ret == 0 || (ret == -1 && errno == EINTR)); + + if (ret == -1) { + error_report("failed to read from TPM device %s: %d", + tpm_proxy->host_path, errno); + return H_RESOURCE; + } + + cpu_physical_memory_write(data_out, buf_out, ret); + args[0] = ret; + + return H_SUCCESS; +} + +static target_ulong h_tpm_comm(PowerPCCPU *cpu, + SpaprMachineState *spapr, + target_ulong opcode, + target_ulong *args) +{ + target_ulong op = args[0]; + SpaprTpmProxy *tpm_proxy = spapr->tpm_proxy; + + if (!tpm_proxy) { + error_report("TPM proxy not available"); + return H_FUNCTION; + } + + trace_spapr_h_tpm_comm(tpm_proxy->host_path ?: "null", op); + + switch (op) { + case TPM_COMM_OP_EXECUTE: + return tpm_execute(tpm_proxy, args); + case TPM_COMM_OP_CLOSE_SESSION: + spapr_tpm_proxy_reset(tpm_proxy); + return H_SUCCESS; + default: + return H_PARAMETER; + } +} + +static void spapr_tpm_proxy_realize(DeviceState *d, Error **errp) +{ + SpaprTpmProxy *tpm_proxy = SPAPR_TPM_PROXY(d); + + if (tpm_proxy->host_path == NULL) { + error_setg(errp, "must specify 'host-path' option for device"); + return; + } + + tpm_proxy->host_fd = -1; + qemu_register_reset(spapr_tpm_proxy_reset, tpm_proxy); +} + +static void spapr_tpm_proxy_unrealize(DeviceState *d, Error **errp) +{ + SpaprTpmProxy *tpm_proxy = SPAPR_TPM_PROXY(d); + + qemu_unregister_reset(spapr_tpm_proxy_reset, tpm_proxy); +} + +static Property spapr_tpm_proxy_properties[] = { + DEFINE_PROP_STRING("host-path", SpaprTpmProxy, host_path), + DEFINE_PROP_END_OF_LIST(), +}; + +static void spapr_tpm_proxy_class_init(ObjectClass *k, void *data) +{ + DeviceClass *dk = DEVICE_CLASS(k); + + dk->realize = spapr_tpm_proxy_realize; + dk->unrealize = spapr_tpm_proxy_unrealize; + dk->user_creatable = true; + dk->props = spapr_tpm_proxy_properties; +} + +static const TypeInfo spapr_tpm_proxy_info = { + .name = TYPE_SPAPR_TPM_PROXY, + .parent = TYPE_DEVICE, + .instance_size = sizeof(SpaprTpmProxy), + .class_init = spapr_tpm_proxy_class_init, +}; + +static void spapr_tpm_proxy_register_types(void) +{ + type_register_static(&spapr_tpm_proxy_info); + spapr_register_hypercall(SVM_H_TPM_COMM, h_tpm_comm); +} + +type_init(spapr_tpm_proxy_register_types) diff --git a/hw/ppc/trace-events b/hw/ppc/trace-events index f76448f532..96dad767a1 100644 --- a/hw/ppc/trace-events +++ b/hw/ppc/trace-events @@ -25,6 +25,10 @@ spapr_update_dt(unsigned cb) "New blob %u bytes" spapr_update_dt_failed_size(unsigned cbold, unsigned cbnew, unsigned magic) "Old blob %u bytes, new blob %u bytes, magic 0x%x" spapr_update_dt_failed_check(unsigned cbold, unsigned cbnew, unsigned magic) "Old blob %u bytes, new blob %u bytes, magic 0x%x" +# spapr_hcall_tpm.c +spapr_h_tpm_comm(const char *device_path, uint64_t operation) "tpm_device_path=%s operation=0x%"PRIu64 +spapr_tpm_execute(uint64_t data_in, uint64_t data_in_sz, uint64_t data_out, uint64_t data_out_sz) "data_in=0x%"PRIx64", data_in_sz=%"PRIu64", data_out=0x%"PRIx64", data_out_sz=%"PRIu64 + # spapr_iommu.c spapr_iommu_put(uint64_t liobn, uint64_t ioba, uint64_t tce, uint64_t ret) "liobn=0x%"PRIx64" ioba=0x%"PRIx64" tce=0x%"PRIx64" ret=%"PRId64 spapr_iommu_get(uint64_t liobn, uint64_t ioba, uint64_t ret, uint64_t tce) "liobn=0x%"PRIx64" ioba=0x%"PRIx64" ret=%"PRId64" tce=0x%"PRIx64 diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 5d36eec9d0..c79bc6a123 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -10,6 +10,7 @@ #include "hw/ppc/spapr_irq.h" #include "hw/ppc/spapr_xive.h" /* For SpaprXive */ #include "hw/ppc/xics.h" /* For ICSState */ +#include "hw/ppc/spapr_tpm_proxy.h" struct SpaprVioBus; struct SpaprPhbState; @@ -203,6 +204,7 @@ struct SpaprMachineState { SpaprCapabilities def, eff, mig; unsigned gpu_numa_id; + SpaprTpmProxy *tpm_proxy; }; #define H_SUCCESS 0 @@ -508,6 +510,15 @@ struct SpaprMachineState { #define KVMPPC_H_UPDATE_DT (KVMPPC_HCALL_BASE + 0x3) #define KVMPPC_HCALL_MAX KVMPPC_H_UPDATE_DT +/* + * The hcall range 0xEF00 to 0xEF80 is reserved for use in facilitating + * Secure VM mode via an Ultravisor / Protected Execution Facility + */ +#define SVM_HCALL_BASE 0xEF00 +#define SVM_H_TPM_COMM 0xEF10 +#define SVM_HCALL_MAX SVM_H_TPM_COMM + + typedef struct SpaprDeviceTreeUpdateHeader { uint32_t version_id; } SpaprDeviceTreeUpdateHeader; diff --git a/include/hw/ppc/spapr_tpm_proxy.h b/include/hw/ppc/spapr_tpm_proxy.h new file mode 100644 index 0000000000..c574e22ba4 --- /dev/null +++ b/include/hw/ppc/spapr_tpm_proxy.h @@ -0,0 +1,31 @@ +/* + * SPAPR TPM Proxy/Hypercall + * + * Copyright IBM Corp. 2019 + * + * Authors: + * Michael Roth + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#ifndef HW_SPAPR_TPM_PROXY_H +#define HW_SPAPR_TPM_PROXY_H + +#include "qom/object.h" +#include "hw/qdev-core.h" + +#define TYPE_SPAPR_TPM_PROXY "spapr-tpm-proxy" +#define SPAPR_TPM_PROXY(obj) OBJECT_CHECK(SpaprTpmProxy, (obj), \ + TYPE_SPAPR_TPM_PROXY) + +typedef struct SpaprTpmProxy { + /*< private >*/ + DeviceState parent; + + char *host_path; + int host_fd; +} SpaprTpmProxy; + +#endif /* HW_SPAPR_TPM_PROXY_H */ From patchwork Wed Aug 21 07:25:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105915 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 39F4A184E for ; Wed, 21 Aug 2019 07:57:34 +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 AE5422332A for ; Wed, 21 Aug 2019 07:57:33 +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="H7L2yax0" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AE5422332A 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]:44758 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LUq-000102-Od for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:57:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42527) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0e-0004wf-EE for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0T-0008B7-Oh for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:20 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:41453) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0S-00084V-08; Wed, 21 Aug 2019 03:26:09 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjC4QQWz9sPb; Wed, 21 Aug 2019 17:25:49 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372351; bh=BGpXr5T5oR7MLoMe6KSc7A7crW8GSdBBC/gZiWy348Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=H7L2yax0k0tA9I77jzZmNN+oc3t0R92kwJeGYnZQZPDtaBFHXvVZfHbzPig8Q0ZXU AatZOHPlQMDCELaI04lcr5i9YDfanO+PM1irYX9I4OCMhErqjXEQj21lE8X5UgBhHW dYIFod4Ay30wUNTgxToJ+JgbkzNn8tLW4uORehWI= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:21 +1000 Message-Id: <20190821072542.23090-22-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 21/42] pseries: Update SLOF firmware image 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, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Alexey Kardashevskiy The only change that SLOF does not rely on QEMU providing an RTAS blob and provides one itself: https://git.qemu.org/?p=SLOF.git;a=commitdiff;h=5e4ed1fd0f39e Signed-off-by: Alexey Kardashevskiy Signed-off-by: David Gibson --- pc-bios/README | 2 +- pc-bios/slof.bin | Bin 926432 -> 926784 bytes roms/SLOF | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pc-bios/README b/pc-bios/README index 68b4a81103..d59cd25461 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-20190703. + built from git tag qemu-slof-20190719. - 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 2def51471772b6091bc5dc19b3bb136dddd201b2..fb0837508be2e398054fe9837682f5eff18875ad 100644 GIT binary patch delta 215196 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
  • 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 X-Patchwork-Id: 11105871 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 8D67013A4 for ; Wed, 21 Aug 2019 07:55:45 +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 6445422D6D for ; Wed, 21 Aug 2019 07:55:45 +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="dBNLcH2S" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6445422D6D 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]:44744 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LT6-0006uO-FB for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:55:44 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42790) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L1B-0005YD-Po for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L1A-0000FD-LW for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:53 -0400 Received: from ozlabs.org ([203.11.71.1]:43093) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L1A-0008SK-AH; Wed, 21 Aug 2019 03:26:52 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjG33Flz9sR8; Wed, 21 Aug 2019 17:25:49 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372354; bh=7bWUvyvMwDHcXO2wfGBuWkd301O7ASe0z8ehsRSbHj4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dBNLcH2SHDkqn2SNejGDkpomBX1R8x9a12OXRDyQmD6eFmcf62NCeM5wFDmgL6y6t iZ/pEc1WjZ+Um97RFm2MLwmiEVYOQkwh6fZSxHkRFQ9t7ToTNzCPbgrE0519fPrff7 sA7qeRaF2W4XcYiFwLd9f3nNXte3ZQAT+Iev8O1I= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:22 +1000 Message-Id: <20190821072542.23090-23-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 22/42] ppc/xive: use an abstract type for XiveNotifier 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, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater Signed-off-by: Cédric Le Goater Message-Id: <20190718115420.19919-2-clg@kaod.org> Signed-off-by: David Gibson --- include/hw/ppc/xive.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index 9399c77d2d..ea6ae34375 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -148,13 +148,11 @@ * XIVE Notifier (Interface between Source and Router) */ -typedef struct XiveNotifier { - Object parent; -} XiveNotifier; +typedef struct XiveNotifier XiveNotifier; #define TYPE_XIVE_NOTIFIER "xive-notifier" #define XIVE_NOTIFIER(obj) \ - OBJECT_CHECK(XiveNotifier, (obj), TYPE_XIVE_NOTIFIER) + INTERFACE_CHECK(XiveNotifier, (obj), TYPE_XIVE_NOTIFIER) #define XIVE_NOTIFIER_CLASS(klass) \ OBJECT_CLASS_CHECK(XiveNotifierClass, (klass), TYPE_XIVE_NOTIFIER) #define XIVE_NOTIFIER_GET_CLASS(obj) \ From patchwork Wed Aug 21 07:25:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105867 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 1B0AD14F7 for ; Wed, 21 Aug 2019 07:53:15 +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 E6D3422DA7 for ; Wed, 21 Aug 2019 07:53: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="gdEJdRnL" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E6D3422DA7 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]:44720 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LQf-0003tX-W5 for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:53:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42588) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0q-0005Bj-3j for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0o-0008Rs-6q for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:31 -0400 Received: from ozlabs.org ([203.11.71.1]:38065) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0m-00086l-Oq; Wed, 21 Aug 2019 03:26:30 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjD6KFSz9sRC; Wed, 21 Aug 2019 17:25:50 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372352; bh=DFkJG95qo/G957L8HxCC42/eteTec5f3+2EJ2gUFXKQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gdEJdRnLZHTSjk6rOyNwBLOXRY39g5YxfyYkp5gO4O/ER+1taPTnasQ/iLJHghTh6 BqTJY+DuHnPV34iF1gZAUietLYxJ+M0mYHZXpMogh3btWwKGIuXYJaHR/GZa2Pxg0K qAN1ERwSJCQTsp0ySAt7N4z2Vx1igyBI2G2Rjc8c= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:23 +1000 Message-Id: <20190821072542.23090-24-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 23/42] ppc/xive: Implement TM_PULL_OS_CTX special command 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, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= , 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 vCPU is not dispatched anymore on a HW thread, the Hypervisor (KVM on Linux) invalidates the OS interrupt context of a vCPU with this special command. It returns the OS CAM line value and resets the VO bit. Signed-off-by: Cédric Le Goater Message-Id: <20190718115420.19919-4-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/xive.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 7a6e4b763a..ab7ce64a83 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -337,6 +337,17 @@ static void xive_tm_set_os_pending(XiveTCTX *tctx, hwaddr offset, xive_tctx_notify(tctx, TM_QW1_OS); } +static uint64_t xive_tm_pull_os_ctx(XiveTCTX *tctx, hwaddr offset, + unsigned size) +{ + uint32_t qw1w2_prev = xive_tctx_word2(&tctx->regs[TM_QW1_OS]); + uint32_t qw1w2; + + qw1w2 = xive_set_field32(TM_QW1W2_VO, qw1w2_prev, 0); + memcpy(&tctx->regs[TM_QW1_OS + TM_WORD2], &qw1w2, 4); + return qw1w2; +} + /* * Define a mapping of "special" operations depending on the TIMA page * offset and the size of the operation. @@ -363,6 +374,8 @@ static const XiveTmOp xive_tm_operations[] = { /* MMIOs above 2K : special operations with side effects */ { XIVE_TM_OS_PAGE, TM_SPC_ACK_OS_REG, 2, NULL, xive_tm_ack_os_reg }, { XIVE_TM_OS_PAGE, TM_SPC_SET_OS_PENDING, 1, xive_tm_set_os_pending, NULL }, + { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX, 4, NULL, xive_tm_pull_os_ctx }, + { XIVE_TM_HV_PAGE, TM_SPC_PULL_OS_CTX, 8, NULL, xive_tm_pull_os_ctx }, { XIVE_TM_HV_PAGE, TM_SPC_ACK_HV_REG, 2, NULL, xive_tm_ack_hv_reg }, { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX, 4, NULL, xive_tm_pull_pool_ctx }, { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX, 8, NULL, xive_tm_pull_pool_ctx }, @@ -406,7 +419,7 @@ void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, uint64_t value, if (offset & 0x800) { xto = xive_tm_find_op(offset, size, true); if (!xto) { - qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid write access at TIMA" + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid write access at TIMA " "@%"HWADDR_PRIx"\n", offset); } else { xto->write_handler(tctx, offset, value, size); From patchwork Wed Aug 21 07:25:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105951 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 05CAD13A4 for ; Wed, 21 Aug 2019 07:59:17 +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 CEF5522D6D for ; Wed, 21 Aug 2019 07:59:16 +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="P1MhiYgz" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CEF5522D6D 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]:44772 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LWV-0002nA-QM for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:59:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42819) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L1D-0005aY-5H for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L1B-0000GD-Tk for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:55 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:54227) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L1B-0008SO-6e; Wed, 21 Aug 2019 03:26:53 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjG4F0wz9sQt; Wed, 21 Aug 2019 17:25:50 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372354; bh=wU5H61CwJkmgDFkNVITD7MVdyA45DnpLl8N5eMfxsL0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=P1MhiYgzTY68Yc0YWoCozd/KAgNwuf/8Fx4YjP7JR0shhFZ6QoEUhaCsWenpUwc/j R8hMx6524AkcVZtP+Uztg6W9jFm0HcEBVE1nD+yMWO7aiSbTzKzT0ykwWHa5gK20kj 74/4OUEjgug0EysJQ/BlTCjEzHx6fvwXTimRbzgQ= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:24 +1000 Message-Id: <20190821072542.23090-25-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 24/42] ppc/xive: Provide backlog support 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, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater If backlog is activated ('b' bit) on the END, the pending priority of a missed event is recorded in the IPB field of the NVT for a later resend. Signed-off-by: Cédric Le Goater Message-Id: <20190718115420.19919-5-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/xive.c | 77 +++++++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 29 deletions(-) diff --git a/hw/intc/xive.c b/hw/intc/xive.c index ab7ce64a83..f27b4e3328 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1411,46 +1411,22 @@ static bool xive_presenter_match(XiveRouter *xrtr, uint8_t format, * * The parameters represent what is sent on the PowerBus */ -static void xive_presenter_notify(XiveRouter *xrtr, uint8_t format, +static bool xive_presenter_notify(XiveRouter *xrtr, uint8_t format, uint8_t nvt_blk, uint32_t nvt_idx, bool cam_ignore, uint8_t priority, uint32_t logic_serv) { - XiveNVT nvt; XiveTCTXMatch match = { .tctx = NULL, .ring = 0 }; bool found; - /* NVT cache lookup */ - if (xive_router_get_nvt(xrtr, nvt_blk, nvt_idx, &nvt)) { - qemu_log_mask(LOG_GUEST_ERROR, "XIVE: no NVT %x/%x\n", - nvt_blk, nvt_idx); - return; - } - - if (!xive_nvt_is_valid(&nvt)) { - qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVT %x/%x is invalid\n", - nvt_blk, nvt_idx); - return; - } - found = xive_presenter_match(xrtr, format, nvt_blk, nvt_idx, cam_ignore, priority, logic_serv, &match); if (found) { ipb_update(&match.tctx->regs[match.ring], priority); xive_tctx_notify(match.tctx, match.ring); - return; } - /* Record the IPB in the associated NVT structure */ - ipb_update((uint8_t *) &nvt.w4, priority); - xive_router_write_nvt(xrtr, nvt_blk, nvt_idx, &nvt, 4); - - /* - * If no matching NVT is dispatched on a HW thread : - * - update the NVT structure if backlog is activated - * - escalate (ESe PQ bits and EAS in w4-5) if escalation is - * activated - */ + return found; } /* @@ -1464,6 +1440,10 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk, XiveEND end; uint8_t priority; uint8_t format; + uint8_t nvt_blk; + uint32_t nvt_idx; + XiveNVT nvt; + bool found; /* END cache lookup */ if (xive_router_get_end(xrtr, end_blk, end_idx, &end)) { @@ -1522,14 +1502,53 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk, /* * Follows IVPE notification */ - xive_presenter_notify(xrtr, format, - xive_get_field32(END_W6_NVT_BLOCK, end.w6), - xive_get_field32(END_W6_NVT_INDEX, end.w6), + nvt_blk = xive_get_field32(END_W6_NVT_BLOCK, end.w6); + nvt_idx = xive_get_field32(END_W6_NVT_INDEX, end.w6); + + /* NVT cache lookup */ + if (xive_router_get_nvt(xrtr, nvt_blk, nvt_idx, &nvt)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: no NVT %x/%x\n", + nvt_blk, nvt_idx); + return; + } + + if (!xive_nvt_is_valid(&nvt)) { + qemu_log_mask(LOG_GUEST_ERROR, "XIVE: NVT %x/%x is invalid\n", + nvt_blk, nvt_idx); + return; + } + + found = xive_presenter_notify(xrtr, format, nvt_blk, nvt_idx, xive_get_field32(END_W7_F0_IGNORE, end.w7), priority, xive_get_field32(END_W7_F1_LOG_SERVER_ID, end.w7)); /* TODO: Auto EOI. */ + + if (found) { + return; + } + + /* + * If no matching NVT is dispatched on a HW thread : + * - specific VP: update the NVT structure if backlog is activated + * - logical server : forward request to IVPE (not supported) + */ + if (xive_end_is_backlog(&end)) { + if (format == 1) { + qemu_log_mask(LOG_GUEST_ERROR, + "XIVE: END %x/%x invalid config: F1 & backlog\n", + end_blk, end_idx); + return; + } + /* Record the IPB in the associated NVT structure */ + ipb_update((uint8_t *) &nvt.w4, priority); + xive_router_write_nvt(xrtr, nvt_blk, nvt_idx, &nvt, 4); + + /* + * On HW, follows a "Broadcast Backlog" to IVPEs + */ + } } void xive_router_notify(XiveNotifier *xn, uint32_t lisn) From patchwork Wed Aug 21 07:25:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105953 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 F12EB13A4 for ; Wed, 21 Aug 2019 08:00:11 +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 C838222CF7 for ; Wed, 21 Aug 2019 08:00:11 +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="aoIxHV/d" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C838222CF7 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]:44784 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LXO-0003xP-JR for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 04:00:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42586) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0q-0005Bg-35 for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0o-0008S5-AZ for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:31 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:60269) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0n-00087E-Qv; Wed, 21 Aug 2019 03:26:30 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjF0wFdz9sQw; Wed, 21 Aug 2019 17:25:50 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372353; bh=hIig2nTissNaV4C54zIncxf4ubr2zTLoxwEtdCEGU1I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aoIxHV/dADnQFl6QGTRf0DrVbigzQcJ9auJGeHn7V+KZ1/UrxH8awG2I/F0pAdUl+ zmlRLRwxeD6qWV50JoEyQvVCqbJJ6MNMz59ke+itpg46MQzlkX5H7OjC5pZAMeLwot GRq/YKvKZFE1fzHojRu3aiCWKbxtzyubLC/ufwsc= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:25 +1000 Message-Id: <20190821072542.23090-26-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 25/42] ppc/xive: Provide escalation support 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, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater If the XIVE presenter can not find the NVT dispatched on any of the HW threads, it can not deliver the interrupt. XIVE offers an escalation mechanism to handle such scenarios and inform the hypervisor that an action should be taken. Escalation is configured by setting the 'e' bit and the EAS in word 4 & 5 to let the HW look for the escalation END on which to trigger a new event. Signed-off-by: Cédric Le Goater Message-Id: <20190718115420.19919-6-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/xive.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hw/intc/xive.c b/hw/intc/xive.c index f27b4e3328..12f0d09df6 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1549,6 +1549,22 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk, * On HW, follows a "Broadcast Backlog" to IVPEs */ } + + /* + * If activated, escalate notification using the ESe PQ bits and + * the EAS in w4-5 + */ + if (!xive_end_is_escalate(&end)) { + return; + } + + /* + * The END trigger becomes an Escalation trigger + */ + xive_router_end_notify(xrtr, + xive_get_field32(END_W4_ESC_END_BLOCK, end.w4), + xive_get_field32(END_W4_ESC_END_INDEX, end.w4), + xive_get_field32(END_W5_ESC_END_DATA, end.w5)); } void xive_router_notify(XiveNotifier *xn, uint32_t lisn) From patchwork Wed Aug 21 07:25:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105791 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 E3121912 for ; Wed, 21 Aug 2019 07:32: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 BA03D2332A for ; Wed, 21 Aug 2019 07:32: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="ODHF3SkA" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BA03D2332A 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]:44482 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L6x-0003MR-C1 for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:32:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42370) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0V-0004h2-Gz for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0T-000896-22 for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:11 -0400 Received: from ozlabs.org ([203.11.71.1]:55445) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0S-00086W-CK; Wed, 21 Aug 2019 03:26:08 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjC6Wb4z9sQr; Wed, 21 Aug 2019 17:25:50 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372351; bh=nD2L+SiGYUChIjp0CrLusuaG7viZyrANK72wGdiR5tM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ODHF3SkAlwP8ouTlUkWwoGY0k6opY/REiHpmhLEfACYd8iXEN7I4OA1aFFZY6SyUk 09OpoC5beumS3dR+W/Pf6lfzSMyUSG8xdgvqdkLaEg6gBQMBWELEJWs/OXX+2nSKut EqvwxdyppYXfarlOHB+XG6p9Qy3IGKSdfOYz/NvY= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:26 +1000 Message-Id: <20190821072542.23090-27-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 26/42] ppc/xive: Provide unconditional escalation support 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, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater When the 'u' bit is set the escalation is said to be 'unconditional' which means that the ESe PQ bits are not used. Introduce a xive_router_end_es_notify() routine to share code with the ESn notification. Signed-off-by: Cédric Le Goater Message-Id: <20190718115420.19919-7-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/xive.c | 44 ++++++++++++++++++++++++++++++-------- include/hw/ppc/xive_regs.h | 2 ++ 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 12f0d09df6..3fe84f3e76 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1429,6 +1429,27 @@ static bool xive_presenter_notify(XiveRouter *xrtr, uint8_t format, return found; } +/* + * Notification using the END ESe/ESn bit (Event State Buffer for + * escalation and notification). Profide futher coalescing in the + * Router. + */ +static bool xive_router_end_es_notify(XiveRouter *xrtr, uint8_t end_blk, + uint32_t end_idx, XiveEND *end, + uint32_t end_esmask) +{ + uint8_t pq = xive_get_field32(end_esmask, end->w1); + bool notify = xive_esb_trigger(&pq); + + if (pq != xive_get_field32(end_esmask, end->w1)) { + end->w1 = xive_set_field32(end_esmask, end->w1, pq); + xive_router_write_end(xrtr, end_blk, end_idx, end, 1); + } + + /* ESe/n[Q]=1 : end of notification */ + return notify; +} + /* * An END trigger can come from an event trigger (IPI or HW) or from * another chip. We don't model the PowerBus but the END trigger @@ -1485,16 +1506,9 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk, * even futher coalescing in the Router */ if (!xive_end_is_notify(&end)) { - uint8_t pq = xive_get_field32(END_W1_ESn, end.w1); - bool notify = xive_esb_trigger(&pq); - - if (pq != xive_get_field32(END_W1_ESn, end.w1)) { - end.w1 = xive_set_field32(END_W1_ESn, end.w1, pq); - xive_router_write_end(xrtr, end_blk, end_idx, &end, 1); - } - /* ESn[Q]=1 : end of notification */ - if (!notify) { + if (!xive_router_end_es_notify(xrtr, end_blk, end_idx, + &end, END_W1_ESn)) { return; } } @@ -1558,6 +1572,18 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk, return; } + /* + * Check the END ESe (Event State Buffer for escalation) for even + * futher coalescing in the Router + */ + if (!xive_end_is_uncond_escalation(&end)) { + /* ESe[Q]=1 : end of notification */ + if (!xive_router_end_es_notify(xrtr, end_blk, end_idx, + &end, END_W1_ESe)) { + return; + } + } + /* * The END trigger becomes an Escalation trigger */ diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h index b0c68ab5f7..4378d7259c 100644 --- a/include/hw/ppc/xive_regs.h +++ b/include/hw/ppc/xive_regs.h @@ -210,6 +210,8 @@ typedef struct XiveEND { #define xive_end_is_notify(end) (be32_to_cpu((end)->w0) & END_W0_UCOND_NOTIFY) #define xive_end_is_backlog(end) (be32_to_cpu((end)->w0) & END_W0_BACKLOG) #define xive_end_is_escalate(end) (be32_to_cpu((end)->w0) & END_W0_ESCALATE_CTL) +#define xive_end_is_uncond_escalation(end) \ + (be32_to_cpu((end)->w0) & END_W0_UNCOND_ESCALATE) static inline uint64_t xive_end_qaddr(XiveEND *end) { From patchwork Wed Aug 21 07:25:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105873 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 403A313A4 for ; Wed, 21 Aug 2019 07:57: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 E654722D6D for ; Wed, 21 Aug 2019 07:57:06 +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="Rtxyf0s/" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E654722D6D 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]:44756 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LUP-00008U-T7 for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:57:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42812) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L1C-0005a3-RG for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L1B-0000Fz-O2 for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:54 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:58457) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L1B-0008SS-6Q; Wed, 21 Aug 2019 03:26:53 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjG4wxZz9sQx; Wed, 21 Aug 2019 17:25:50 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372354; bh=w8jJ4HioXwrN0ISowEXNExCB5N6zlcEr6dihcQPI6D0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Rtxyf0s/tsHX4/mTTvBBggoE/aBraVGmqVs81Wl/AMAXuOxrH0zBpbLuM1RA79XuW Em/SomeCtHyFwgPbn/5VJzZhTpjacz+/9dBwyscafe3EGx1AFuosmetbUaG/sFc2jc 6KKE9MS5cv1gq5z5CRVvr4m1wE5ORIbQxNY8TWQ8= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:27 +1000 Message-Id: <20190821072542.23090-28-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 27/42] ppc/xive: Provide silent escalation support 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, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater When the 's' bit is set the escalation is said to be 'silent' or 'silent/gather'. In such configuration, the notification sequence is skipped and only the escalation sequence is performed. This is used to configure all the EQs of a vCPU to escalate on a single EQ which will then target the hypervisor. Signed-off-by: Cédric Le Goater Message-Id: <20190718115420.19919-8-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/xive.c | 8 ++++++++ include/hw/ppc/xive_regs.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 3fe84f3e76..dd7d02dfdf 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1485,6 +1485,13 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk, xive_router_write_end(xrtr, end_blk, end_idx, &end, 1); } + /* + * When the END is silent, we skip the notification part. + */ + if (xive_end_is_silent_escalation(&end)) { + goto do_escalation; + } + /* * The W7 format depends on the F bit in W6. It defines the type * of the notification : @@ -1564,6 +1571,7 @@ static void xive_router_end_notify(XiveRouter *xrtr, uint8_t end_blk, */ } +do_escalation: /* * If activated, escalate notification using the ESe PQ bits and * the EAS in w4-5 diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h index 4378d7259c..fed019516f 100644 --- a/include/hw/ppc/xive_regs.h +++ b/include/hw/ppc/xive_regs.h @@ -212,6 +212,8 @@ typedef struct XiveEND { #define xive_end_is_escalate(end) (be32_to_cpu((end)->w0) & END_W0_ESCALATE_CTL) #define xive_end_is_uncond_escalation(end) \ (be32_to_cpu((end)->w0) & END_W0_UNCOND_ESCALATE) +#define xive_end_is_silent_escalation(end) \ + (be32_to_cpu((end)->w0) & END_W0_SILENT_ESCALATE) static inline uint64_t xive_end_qaddr(XiveEND *end) { From patchwork Wed Aug 21 07:25:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105851 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 7B4AA13A4 for ; Wed, 21 Aug 2019 07:47:53 +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 521C22339F for ; Wed, 21 Aug 2019 07:47:53 +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="QOAxykke" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 521C22339F 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]:44638 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LLT-0005Tb-NX for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:47:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42647) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0t-0005Cb-5B for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0r-0008VX-8N for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:35 -0400 Received: from ozlabs.org ([203.11.71.1]:56229) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0q-0008By-2X; Wed, 21 Aug 2019 03:26:33 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjF5rXVz9sRH; Wed, 21 Aug 2019 17:25:50 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372353; bh=1Q7kUffIK/q+bkepDdlCPRGhFzWFmhrw1SDlMqdonxc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QOAxykkec1gaJwXq9XKBq0cXZDziI01zhFzvrGES1LRuCV5siOkzIQ5vG38uewiI9 yrRT/mFn9kSBjJSsJwued5g3Vm0x10gBQNNOlvCo+KaqcqmEPQzWuSlegXIW0MhSal nzWABwuamP465KN9Ial77mYahA5GfhMKzNFMS2X8= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:28 +1000 Message-Id: <20190821072542.23090-29-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 28/42] ppc/xive: Improve 'info pic' support 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, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater Provide a better output of the XIVE END structures including the escalation information and extend the PowerNV machine 'info pic' command with a dump of the END EAS table used for escalations. Signed-off-by: Cédric Le Goater Message-Id: <20190718115420.19919-9-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/pnv_xive.c | 9 +++++++ hw/intc/spapr_xive.c | 1 - hw/intc/xive.c | 48 +++++++++++++++++++++++++++++++++----- include/hw/ppc/xive.h | 5 ---- include/hw/ppc/xive_regs.h | 6 +++++ 5 files changed, 57 insertions(+), 12 deletions(-) diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c index a8caf258fd..ed6e9d71bb 100644 --- a/hw/intc/pnv_xive.c +++ b/hw/intc/pnv_xive.c @@ -1595,6 +1595,15 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon) } xive_end_pic_print_info(&end, i, mon); } + + monitor_printf(mon, "XIVE[%x] END Escalation %08x .. %08x\n", blk, 0, + nr_ends - 1); + for (i = 0; i < nr_ends; i++) { + if (xive_router_get_end(xrtr, blk, i, &end)) { + break; + } + xive_end_eas_pic_print_info(&end, i, mon); + } } static void pnv_xive_reset(void *dev) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index aad981cb78..a29b48edf7 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -146,7 +146,6 @@ static void spapr_xive_end_pic_print_info(SpaprXive *xive, XiveEND *end, priority, qindex, qentries, qaddr_base, qgen); xive_end_queue_pic_print_info(end, 6, mon); - monitor_printf(mon, "]"); } void spapr_xive_pic_print_info(SpaprXive *xive, Monitor *mon) diff --git a/hw/intc/xive.c b/hw/intc/xive.c index dd7d02dfdf..b7417210d8 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1158,6 +1158,7 @@ void xive_end_queue_pic_print_info(XiveEND *end, uint32_t width, Monitor *mon) be32_to_cpu(qdata)); qindex = (qindex + 1) & (qentries - 1); } + monitor_printf(mon, "]"); } void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon) @@ -1168,24 +1169,36 @@ void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon) uint32_t qsize = xive_get_field32(END_W0_QSIZE, end->w0); uint32_t qentries = 1 << (qsize + 10); - uint32_t nvt = xive_get_field32(END_W6_NVT_INDEX, end->w6); + uint32_t nvt_blk = xive_get_field32(END_W6_NVT_BLOCK, end->w6); + uint32_t nvt_idx = xive_get_field32(END_W6_NVT_INDEX, end->w6); uint8_t priority = xive_get_field32(END_W7_F0_PRIORITY, end->w7); + uint8_t pq; if (!xive_end_is_valid(end)) { return; } - monitor_printf(mon, " %08x %c%c%c%c%c prio:%d nvt:%04x eq:@%08"PRIx64 - "% 6d/%5d ^%d", end_idx, + pq = xive_get_field32(END_W1_ESn, end->w1); + + monitor_printf(mon, " %08x %c%c %c%c%c%c%c%c%c prio:%d nvt:%02x/%04x", + end_idx, + pq & XIVE_ESB_VAL_P ? 'P' : '-', + pq & XIVE_ESB_VAL_Q ? 'Q' : '-', xive_end_is_valid(end) ? 'v' : '-', xive_end_is_enqueue(end) ? 'q' : '-', xive_end_is_notify(end) ? 'n' : '-', xive_end_is_backlog(end) ? 'b' : '-', xive_end_is_escalate(end) ? 'e' : '-', - priority, nvt, qaddr_base, qindex, qentries, qgen); + xive_end_is_uncond_escalation(end) ? 'u' : '-', + xive_end_is_silent_escalation(end) ? 's' : '-', + priority, nvt_blk, nvt_idx); - xive_end_queue_pic_print_info(end, 6, mon); - monitor_printf(mon, "]\n"); + if (qaddr_base) { + monitor_printf(mon, " eq:@%08"PRIx64"% 6d/%5d ^%d", + qaddr_base, qindex, qentries, qgen); + xive_end_queue_pic_print_info(end, 6, mon); + } + monitor_printf(mon, "\n"); } static void xive_end_enqueue(XiveEND *end, uint32_t data) @@ -1213,6 +1226,29 @@ static void xive_end_enqueue(XiveEND *end, uint32_t data) end->w1 = xive_set_field32(END_W1_PAGE_OFF, end->w1, qindex); } +void xive_end_eas_pic_print_info(XiveEND *end, uint32_t end_idx, + Monitor *mon) +{ + XiveEAS *eas = (XiveEAS *) &end->w4; + uint8_t pq; + + if (!xive_end_is_escalate(end)) { + return; + } + + pq = xive_get_field32(END_W1_ESe, end->w1); + + monitor_printf(mon, " %08x %c%c %c%c end:%02x/%04x data:%08x\n", + end_idx, + pq & XIVE_ESB_VAL_P ? 'P' : '-', + pq & XIVE_ESB_VAL_Q ? 'Q' : '-', + xive_eas_is_valid(eas) ? 'V' : ' ', + xive_eas_is_masked(eas) ? 'M' : ' ', + (uint8_t) xive_get_field64(EAS_END_BLOCK, eas->w), + (uint32_t) xive_get_field64(EAS_END_INDEX, eas->w), + (uint32_t) xive_get_field64(EAS_END_DATA, eas->w)); +} + /* * XIVE Router (aka. Virtualization Controller or IVRE) */ diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index ea6ae34375..6d38755f84 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -354,8 +354,6 @@ typedef struct XiveRouterClass { XiveTCTX *(*get_tctx)(XiveRouter *xrtr, CPUState *cs); } XiveRouterClass; -void xive_eas_pic_print_info(XiveEAS *eas, uint32_t lisn, Monitor *mon); - int xive_router_get_eas(XiveRouter *xrtr, uint8_t eas_blk, uint32_t eas_idx, XiveEAS *eas); int xive_router_get_end(XiveRouter *xrtr, uint8_t end_blk, uint32_t end_idx, @@ -397,9 +395,6 @@ typedef struct XiveENDSource { */ #define XIVE_PRIORITY_MAX 7 -void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon); -void xive_end_queue_pic_print_info(XiveEND *end, uint32_t width, Monitor *mon); - /* * XIVE Thread Interrupt Management Aera (TIMA) * diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h index fed019516f..08c8bf7172 100644 --- a/include/hw/ppc/xive_regs.h +++ b/include/hw/ppc/xive_regs.h @@ -131,6 +131,8 @@ typedef struct XiveEAS { #define xive_eas_is_valid(eas) (be64_to_cpu((eas)->w) & EAS_VALID) #define xive_eas_is_masked(eas) (be64_to_cpu((eas)->w) & EAS_MASKED) +void xive_eas_pic_print_info(XiveEAS *eas, uint32_t lisn, Monitor *mon); + static inline uint64_t xive_get_field64(uint64_t mask, uint64_t word) { return (be64_to_cpu(word) & mask) >> ctz64(mask); @@ -221,6 +223,10 @@ static inline uint64_t xive_end_qaddr(XiveEND *end) be32_to_cpu(end->w3); } +void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon); +void xive_end_queue_pic_print_info(XiveEND *end, uint32_t width, Monitor *mon); +void xive_end_eas_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon); + /* Notification Virtual Target (NVT) */ typedef struct XiveNVT { uint32_t w0; From patchwork Wed Aug 21 07:25:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105843 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 CF4FC912 for ; Wed, 21 Aug 2019 07:44: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 A5DBC233A0 for ; Wed, 21 Aug 2019 07:44: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="qQowfhqO" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A5DBC233A0 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]:44592 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LHq-0001U6-Lq for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:44:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42574) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0p-0005BY-8X for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0o-0008Rl-6p for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:31 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:44673) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0n-00086s-0S; Wed, 21 Aug 2019 03:26:30 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjD49d6z9sR7; Wed, 21 Aug 2019 17:25:50 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372352; bh=djbVlC8N25YL//fyM3PhmQf5jm2n/3eUfbuieIBOl9o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qQowfhqOTbcnlBwz5AOmRwL4l2heczzKI2Htz8slsYmJWeF9NqOJhOXOXUs58JJZt iVM7dOYyaDEEdooO/i6UxLWMJ5Tg2kjufFPPTRfzqvHBHVMiL3lEoAw5VyzSeGrHz/ jeGCc4qSpNhjh0Ubub/ZhfF9OIPosX/5O0G4rAvw= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:29 +1000 Message-Id: <20190821072542.23090-30-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 29/42] machine: Add wakeup method to MachineClass 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, aik@ozlabs.ru, qemu-devel@nongnu.org, Nicholas Piggin , groug@kaod.org, qemu-ppc@nongnu.org, Paolo Bonzini , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Nicholas Piggin Waking from suspend is not logically a machine reset on all machines, particularly in the paravirtualized case rather than hardware emulated. The ppc spapr machine for example just invokes hypervisor to suspend, and expects that call to return with the machine in the same state (modulo some possible migration and reconfiguration details). Implement a machine ->wakeup method and use that if it exists. Signed-off-by: Nicholas Piggin Message-Id: <20190722053215.20808-2-npiggin@gmail.com> Acked-by: Paolo Bonzini Signed-off-by: David Gibson --- include/hw/boards.h | 1 + vl.c | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/hw/boards.h b/include/hw/boards.h index aa35955f7f..60d69217b4 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -180,6 +180,7 @@ struct MachineClass { void (*init)(MachineState *state); void (*reset)(MachineState *state); + void (*wakeup)(MachineState *state); void (*hot_add_cpu)(MachineState *state, const int64_t id, Error **errp); int (*kvm_type)(MachineState *machine, const char *arg); void (*smp_parse)(MachineState *ms, QemuOpts *opts); diff --git a/vl.c b/vl.c index edd5390110..09aa18cb35 100644 --- a/vl.c +++ b/vl.c @@ -1557,6 +1557,22 @@ void qemu_system_reset(ShutdownCause reason) cpu_synchronize_all_post_reset(); } +/* + * Wake the VM after suspend. + */ +static void qemu_system_wakeup(void) +{ + MachineClass *mc; + + mc = current_machine ? MACHINE_GET_CLASS(current_machine) : NULL; + + if (mc && mc->wakeup) { + mc->wakeup(current_machine); + } else { + qemu_system_reset(SHUTDOWN_CAUSE_NONE); + } +} + void qemu_system_guest_panicked(GuestPanicInformation *info) { qemu_log_mask(LOG_GUEST_ERROR, "Guest crashed"); @@ -1765,7 +1781,7 @@ static bool main_loop_should_exit(void) } if (qemu_wakeup_requested()) { pause_all_vcpus(); - qemu_system_reset(SHUTDOWN_CAUSE_NONE); + qemu_system_wakeup(); notifier_list_notify(&wakeup_notifiers, &wakeup_reason); wakeup_reason = QEMU_WAKEUP_REASON_NONE; resume_all_vcpus(); From patchwork Wed Aug 21 07:25:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105965 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 41B9E13B1 for ; Wed, 21 Aug 2019 08:05:31 +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 17BB022D6D for ; Wed, 21 Aug 2019 08:05:31 +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="dZj5RMiG" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 17BB022D6D 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]:44862 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LcY-0003NQ-9i for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 04:05:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42791) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L1B-0005YE-Pi for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L1A-0000FJ-MJ for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:53 -0400 Received: from ozlabs.org ([203.11.71.1]:54309) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L1A-0008SJ-BX; Wed, 21 Aug 2019 03:26:52 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjG0Cslz9sR2; Wed, 21 Aug 2019 17:25:51 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372354; bh=swC+cfrA6RL8IRtZkusa0ebY3i0bciClde+gKNL4MyE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dZj5RMiGCyDjmfPw6sqioOvZ4jsGPWsmbN7kQViYxzzbr+i+KbF+/KWhoQBGSCLA3 eoyu7depvcs9OPsTufgBUDH1quQsr4BQkF0DQjRqB4FAgQfj4KBBgRawcu+35AkUeV yB+cX+e1OZwaSb+sdSkihhhpK1M4ZEZMmjeta1JI= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:30 +1000 Message-Id: <20190821072542.23090-31-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 30/42] i386: use machine class ->wakeup method 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, aik@ozlabs.ru, qemu-devel@nongnu.org, Nicholas Piggin , groug@kaod.org, qemu-ppc@nongnu.org, Paolo Bonzini , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Nicholas Piggin Move the i386 suspend_wakeup logic out of the fallback path, and into the new ->wakeup method. Signed-off-by: Nicholas Piggin Message-Id: <20190722061752.22114-1-npiggin@gmail.com> Acked-by: Paolo Bonzini Signed-off-by: David Gibson --- hw/i386/pc.c | 8 ++++++++ vl.c | 2 -- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 95edbbfe9e..98581fe0c2 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -2834,6 +2834,13 @@ static void pc_machine_reset(MachineState *machine) } } +static void pc_machine_wakeup(MachineState *machine) +{ + cpu_synchronize_all_states(); + pc_machine_reset(machine); + cpu_synchronize_all_post_reset(); +} + static CpuInstanceProperties pc_cpu_index_to_props(MachineState *ms, unsigned cpu_index) { @@ -2946,6 +2953,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) mc->block_default_type = IF_IDE; mc->max_cpus = 255; mc->reset = pc_machine_reset; + mc->wakeup = pc_machine_wakeup; hc->pre_plug = pc_machine_device_pre_plug_cb; hc->plug = pc_machine_device_plug_cb; hc->unplug_request = pc_machine_device_unplug_request_cb; diff --git a/vl.c b/vl.c index 09aa18cb35..8e5af7501f 100644 --- a/vl.c +++ b/vl.c @@ -1568,8 +1568,6 @@ static void qemu_system_wakeup(void) if (mc && mc->wakeup) { mc->wakeup(current_machine); - } else { - qemu_system_reset(SHUTDOWN_CAUSE_NONE); } } From patchwork Wed Aug 21 07:25:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105973 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 DD7331805 for ; Wed, 21 Aug 2019 08:06:33 +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 B502722D6D for ; Wed, 21 Aug 2019 08:06:33 +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="EVtykKP3" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B502722D6D 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]:44888 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LdY-0004VM-Vf for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 04:06:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42884) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L1F-0005dp-8W for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L1D-0000Hc-PS for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:57 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:42595) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L1D-0008V7-3N; Wed, 21 Aug 2019 03:26:55 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjG5mS9z9sR1; Wed, 21 Aug 2019 17:25:51 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372354; bh=+KW+voBQ7BzgDYq6pRx5WSron5t+f80yIV8x/ugXkfY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EVtykKP3nmY0feElibJsnp7F+C8GkPl/VJJtATZGjDdkTJ8ueJLKQQrSQ0kjVOlXz b9bEJ0nh77A9nLWI4ZdwrbK9zyXnRSr7OnmFvQOuSRuzEXN+V2B93uAhZg9EUGgT/1 8AJhYimqDsmMFrrzJxrZqjBjfp+XYD6O60cmRdW4= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:31 +1000 Message-Id: <20190821072542.23090-32-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 31/42] spapr: Implement ibm,suspend-me 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, aik@ozlabs.ru, qemu-devel@nongnu.org, Nicholas Piggin , groug@kaod.org, qemu-ppc@nongnu.org, Paolo Bonzini , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Nicholas Piggin This has been useful to modify and test the Linux pseries suspend code but it requires modification to the guest to call it (due to being gated by other unimplemented features). It is not otherwise used by Linux yet, but work is slowly progressing there. This allows a (lightly modified) guest kernel to suspend with `echo mem > /sys/power/state` and be resumed with system_wakeup monitor command. Signed-off-by: Nicholas Piggin Message-Id: <20190722061752.22114-2-npiggin@gmail.com> Acked-by: Paolo Bonzini Signed-off-by: David Gibson --- hw/ppc/spapr.c | 7 +++++++ hw/ppc/spapr_rtas.c | 32 ++++++++++++++++++++++++++++++++ include/hw/ppc/spapr.h | 3 ++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 56b33571c5..51e1cb0d46 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3083,6 +3083,13 @@ static void spapr_machine_init(MachineState *machine) qemu_register_boot_set(spapr_boot_set, spapr); + /* + * Nothing needs to be done to resume a suspended guest because + * suspending does not change the machine state, so no need for + * a ->wakeup method. + */ + qemu_register_wakeup_support(); + if (kvm_enabled()) { /* to stop and start vmclock */ qemu_add_vm_change_state_handler(cpu_ppc_clock_vm_state_change, diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index d3f9a69a51..526b489297 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -217,6 +217,36 @@ static void rtas_stop_self(PowerPCCPU *cpu, SpaprMachineState *spapr, qemu_cpu_kick(cs); } +static void rtas_ibm_suspend_me(PowerPCCPU *cpu, SpaprMachineState *spapr, + uint32_t token, uint32_t nargs, + target_ulong args, + uint32_t nret, target_ulong rets) +{ + CPUState *cs; + + if (nargs != 0 || nret != 1) { + rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); + return; + } + + CPU_FOREACH(cs) { + PowerPCCPU *c = POWERPC_CPU(cs); + CPUPPCState *e = &c->env; + if (c == cpu) { + continue; + } + + /* See h_join */ + if (!cs->halted || (e->msr & (1ULL << MSR_EE))) { + rtas_st(rets, 0, H_MULTI_THREADS_ACTIVE); + return; + } + } + + qemu_system_suspend_request(); + rtas_st(rets, 0, RTAS_OUT_SUCCESS); +} + static inline int sysparm_st(target_ulong addr, target_ulong len, const void *val, uint16_t vallen) { @@ -484,6 +514,8 @@ static void core_rtas_register_types(void) rtas_query_cpu_stopped_state); spapr_rtas_register(RTAS_START_CPU, "start-cpu", rtas_start_cpu); spapr_rtas_register(RTAS_STOP_SELF, "stop-self", rtas_stop_self); + spapr_rtas_register(RTAS_IBM_SUSPEND_ME, "ibm,suspend-me", + rtas_ibm_suspend_me); spapr_rtas_register(RTAS_IBM_GET_SYSTEM_PARAMETER, "ibm,get-system-parameter", rtas_ibm_get_system_parameter); diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index c79bc6a123..fa7c380edb 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -642,8 +642,9 @@ target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode, #define RTAS_IBM_CREATE_PE_DMA_WINDOW (RTAS_TOKEN_BASE + 0x27) #define RTAS_IBM_REMOVE_PE_DMA_WINDOW (RTAS_TOKEN_BASE + 0x28) #define RTAS_IBM_RESET_PE_DMA_WINDOW (RTAS_TOKEN_BASE + 0x29) +#define RTAS_IBM_SUSPEND_ME (RTAS_TOKEN_BASE + 0x2A) -#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x2A) +#define RTAS_TOKEN_MAX (RTAS_TOKEN_BASE + 0x2B) /* RTAS ibm,get-system-parameter token values */ #define RTAS_SYSPARM_SPLPAR_CHARACTERISTICS 20 From patchwork Wed Aug 21 07:25:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105957 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 074CA912 for ; Wed, 21 Aug 2019 08:00:43 +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 D158F22D6D for ; Wed, 21 Aug 2019 08:00:42 +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="f/6bKuM/" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D158F22D6D 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]:44790 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LXt-0005Aa-Fj for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 04:00:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42887) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L1F-0005dv-B9 for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L1D-0000HM-MS for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:57 -0400 Received: from ozlabs.org ([203.11.71.1]:44999) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L1D-0008V3-37; Wed, 21 Aug 2019 03:26:55 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjG6kBqz9sR5; Wed, 21 Aug 2019 17:25:51 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372354; bh=JvTyhoY02W3DptPDPZ0esZT0tYoex1tMvFPextlvu7c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=f/6bKuM/0nBMUNwrqcu+vZOGc655MQKccZr0pQehB1D3yTY/rO+vzm6sZnH4M/eg3 Wlt/rDTNjCHqlcJvPFNqXFK0kT8X//J7O6EuR3LkJ6/3UxLm05pLyDJqxQsfCY2FkC 0MHy3fF0+5IjuAzPiLAwoytLQA+ihxRecJmWwGGo= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:32 +1000 Message-Id: <20190821072542.23090-33-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 32/42] ppc: remove idle_timer logic 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, Shivaprasad G Bhat , aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Shivaprasad G Bhat The logic is broken for multiple vcpu guests, also causing memory leak. The logic is in place to handle kvm not having KVM_CAP_PPC_IRQ_LEVEL, which is part of the kernel now since 2.6.37. Instead of fixing the leak, drop the redundant logic which is not excercised on new kernels anymore. Exit with error on older kernels. Signed-off-by: Shivaprasad G Bhat Message-Id: <156406409479.19996.7606556689856621111.stgit@lep8c.aus.stglabs.ibm.com> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- target/ppc/kvm.c | 75 ++++-------------------------------------------- 1 file changed, 5 insertions(+), 70 deletions(-) diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 6162a903fa..8c5b1f25cc 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -58,7 +58,6 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = { }; static int cap_interrupt_unset; -static int cap_interrupt_level; static int cap_segstate; static int cap_booke_sregs; static int cap_ppc_smt; @@ -89,25 +88,6 @@ static int cap_large_decr; static uint32_t debug_inst_opcode; -/* - * XXX We have a race condition where we actually have a level triggered - * interrupt, but the infrastructure can't expose that yet, so the guest - * takes but ignores it, goes to sleep and never gets notified that there's - * still an interrupt pending. - * - * As a quick workaround, let's just wake up again 20 ms after we injected - * an interrupt. That way we can assure that we're always reinjecting - * interrupts in case the guest swallowed them. - */ -static QEMUTimer *idle_timer; - -static void kvm_kick_cpu(void *opaque) -{ - PowerPCCPU *cpu = opaque; - - qemu_cpu_kick(CPU(cpu)); -} - /* * Check whether we are running with KVM-PR (instead of KVM-HV). This * should only be used for fallback tests - generally we should use @@ -127,7 +107,6 @@ static int kvmppc_get_dec_bits(void); int kvm_arch_init(MachineState *ms, KVMState *s) { cap_interrupt_unset = kvm_check_extension(s, KVM_CAP_PPC_UNSET_IRQ); - cap_interrupt_level = kvm_check_extension(s, KVM_CAP_PPC_IRQ_LEVEL); cap_segstate = kvm_check_extension(s, KVM_CAP_PPC_SEGSTATE); cap_booke_sregs = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_SREGS); cap_ppc_smt_possible = kvm_vm_check_extension(s, KVM_CAP_PPC_SMT_POSSIBLE); @@ -163,9 +142,9 @@ int kvm_arch_init(MachineState *ms, KVMState *s) */ cap_ppc_pvr_compat = false; - if (!cap_interrupt_level) { - fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the " - "VM to stall at times!\n"); + if (!kvm_check_extension(s, KVM_CAP_PPC_IRQ_LEVEL)) { + error_report("KVM: Host kernel doesn't have level irq capability"); + exit(1); } kvm_ppc_register_host_cpu_type(ms); @@ -493,8 +472,6 @@ int kvm_arch_init_vcpu(CPUState *cs) return ret; } - idle_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, kvm_kick_cpu, cpu); - switch (cenv->mmu_model) { case POWERPC_MMU_BOOKE206: /* This target supports access to KVM's guest TLB */ @@ -1334,7 +1311,7 @@ int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level) return 0; } - if (!kvm_enabled() || !cap_interrupt_unset || !cap_interrupt_level) { + if (!kvm_enabled() || !cap_interrupt_unset) { return 0; } @@ -1351,49 +1328,7 @@ int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level) void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) { - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - int r; - unsigned irq; - - qemu_mutex_lock_iothread(); - - /* - * PowerPC QEMU tracks the various core input pins (interrupt, - * critical interrupt, reset, etc) in PPC-specific - * env->irq_input_state. - */ - if (!cap_interrupt_level && - run->ready_for_interrupt_injection && - (cs->interrupt_request & CPU_INTERRUPT_HARD) && - (env->irq_input_state & (1 << PPC_INPUT_INT))) - { - /* - * For now KVM disregards the 'irq' argument. However, in the - * future KVM could cache it in-kernel to avoid a heavyweight - * exit when reading the UIC. - */ - irq = KVM_INTERRUPT_SET; - - trace_kvm_injected_interrupt(irq); - r = kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &irq); - if (r < 0) { - printf("cpu %d fail inject %x\n", cs->cpu_index, irq); - } - - /* Always wake up soon in case the interrupt was level based */ - timer_mod(idle_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - (NANOSECONDS_PER_SECOND / 50)); - } - - /* - * We don't know if there are more interrupts pending after - * this. However, the guest will return to userspace in the course - * of handling this one anyways, so we will get a chance to - * deliver the rest. - */ - - qemu_mutex_unlock_iothread(); + return; } MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) From patchwork Wed Aug 21 07:25:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105823 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 10B5C912 for ; Wed, 21 Aug 2019 07:37: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 DC0A722CE3 for ; Wed, 21 Aug 2019 07:37:26 +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="cisTeu91" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DC0A722CE3 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]:44512 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LBN-0000gW-DU for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:37:25 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42389) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0V-0004hj-Sf for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0T-00089j-EI for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:11 -0400 Received: from ozlabs.org ([203.11.71.1]:38131) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0S-00086j-NU; Wed, 21 Aug 2019 03:26:09 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjD2fBwz9sRG; Wed, 21 Aug 2019 17:25:51 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372352; bh=4T/RugTmxVtT8zm+dzl4xl8xrPpUGZdfYGoB7p6Qn5k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cisTeu91uUN7vgJCvXsFnF/zz9vlGXHA+LIInCy16KEtWYqgHSGZVADkOyH6keycu EqrXmcrXei1JwHXHF33yGLUywBh2FUx7x+WkfO5GwFXKCe8Jqtrn3dcNVABVfEhiSJ EY+AkqZ4P67+3nnjrsSnDdmeE6zfRMCoIQHsdGdI= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:33 +1000 Message-Id: <20190821072542.23090-34-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 33/42] spapr/pci: Consolidate de-allocation of MSIs 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, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Greg Kurz When freeing MSIs, we need to: - remove them from the machine's MSI bitmap - remove them from the IC backend - remove them from the PHB's MSI cache This is currently open coded in two places in rtas_ibm_change_msi(), and we're about to need this in spapr_phb_reset() as well. Instead of duplicating this code again, make it a destroy function for the PHB's MSI cache. Removing an MSI device from the cache will call the destroy function internally. Signed-off-by: Greg Kurz Message-Id: <156415227855.1064338.5657793835271464648.stgit@bahia.lan> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/ppc/spapr_pci.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 4c5420c465..6e6b4d0f60 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -338,10 +338,6 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, SpaprMachineState *spapr, return; } - if (!smc->legacy_irq_allocation) { - spapr_irq_msi_free(spapr, msi->first_irq, msi->num); - } - spapr_irq_free(spapr, msi->first_irq, msi->num); if (msi_present(pdev)) { spapr_msi_setmsg(pdev, 0, false, 0, 0); } @@ -411,10 +407,6 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, SpaprMachineState *spapr, /* Release previous MSIs */ if (msi) { - if (!smc->legacy_irq_allocation) { - spapr_irq_msi_free(spapr, msi->first_irq, msi->num); - } - spapr_irq_free(spapr, msi->first_irq, msi->num); g_hash_table_remove(phb->msi, &config_addr); } @@ -1808,6 +1800,19 @@ static void spapr_phb_unrealize(DeviceState *dev, Error **errp) memory_region_del_subregion(get_system_memory(), &sphb->mem32window); } +static void spapr_phb_destroy_msi(gpointer opaque) +{ + SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); + SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); + spapr_pci_msi *msi = opaque; + + if (!smc->legacy_irq_allocation) { + spapr_irq_msi_free(spapr, msi->first_irq, msi->num); + } + spapr_irq_free(spapr, msi->first_irq, msi->num); + g_free(msi); +} + static void spapr_phb_realize(DeviceState *dev, Error **errp) { /* We don't use SPAPR_MACHINE() in order to exit gracefully if the user @@ -2019,7 +2024,8 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) spapr_tce_get_iommu(tcet)); } - sphb->msi = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free); + sphb->msi = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, + spapr_phb_destroy_msi); return; unrealize: From patchwork Wed Aug 21 07:25:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105841 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 A741E912 for ; Wed, 21 Aug 2019 07:43: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 7A99C2339F for ; Wed, 21 Aug 2019 07:43: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="UwtbdpJQ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7A99C2339F 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]:44586 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LGu-0000HO-8W for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:43:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42648) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0t-0005Cc-5O for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0s-0008WU-3C for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:35 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:58895) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0r-0008SN-6U; Wed, 21 Aug 2019 03:26:33 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjG1gy1z9sR4; Wed, 21 Aug 2019 17:25:51 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372354; bh=QARuwKhSE++Gm/g/XBmuh7qM1lgGrxAx08cn8npusc0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UwtbdpJQHATmipJJbpYeBMKvk9AvPoxDYc9oIoQFPlwBYWkggb4/S0L1UpBIqLvxW 7fVFXFLq3l2uviOZChCZPUmbMvO7FhAyNuPE38SruMvF820SdGHHv6flEpqqSKNPK+ f1OdD0IUM1xJ/8P1U2I/7tGiAdkGS6IIShvy5qow= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:34 +1000 Message-Id: <20190821072542.23090-35-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 34/42] spapr/pci: Free MSIs during reset 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, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= , =?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 When the machine is reset, the MSI bitmap is cleared but the allocated MSIs are not freed. Some operating systems, such as AIX, can detect the previous configuration and assert. Empty the MSI cache, this performs the needed cleanup. Signed-off-by: Greg Kurz Message-Id: <156415228410.1064338.4486161194061636096.stgit@bahia.lan> Reviewed-by: Cédric Le Goater Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/ppc/spapr_pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 6e6b4d0f60..deb0b0c80c 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -2080,6 +2080,8 @@ static void spapr_phb_reset(DeviceState *qdev) if (spapr_phb_eeh_available(SPAPR_PCI_HOST_BRIDGE(qdev))) { spapr_phb_vfio_reset(qdev); } + + g_hash_table_remove_all(sphb->msi); } static Property spapr_phb_properties[] = { From patchwork Wed Aug 21 07:25:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105961 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 640DD912 for ; Wed, 21 Aug 2019 08:03:05 +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 3AFF122D6D for ; Wed, 21 Aug 2019 08:03:05 +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="PVlliHW6" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3AFF122D6D 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]:44818 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LaC-0008Em-9B for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 04:03:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42585) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0q-0005Bb-2B for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0o-0008Ri-6n for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:31 -0400 Received: from ozlabs.org ([203.11.71.1]:41709) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0m-00086k-NU; Wed, 21 Aug 2019 03:26:29 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjD4w7Dz9sR3; Wed, 21 Aug 2019 17:25:51 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372352; bh=c+EmIbgga9qhHKchaVJfp3Gud/L+/Rf9uswnPZgRVJw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PVlliHW65k94TdXB0EF/obHFSaqP21jdpnA3IknQifzlTzVnrLc09o5D43wVxzozF OL3bggLPfZJ+ucqNRY69dgApRPLHnut/0jj9SizewS6eQKUuHPjSbfEtkf0laUVse/ tQT2+OAp/Vf+UN0uLnxJIYtXzdA9wRXsv/Vru+U8= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:35 +1000 Message-Id: <20190821072542.23090-36-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 35/42] spapr/irq: Drop spapr_irq_msi_reset() 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, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Greg Kurz PHBs already take care of clearing the MSIs from the bitmap during reset or unplug. No need to do this globally from the machine code. Rather add an assert to ensure that PHBs have acted as expected. Signed-off-by: Greg Kurz Message-Id: <156415228966.1064338.190189424190233355.stgit@bahia.lan> Reviewed-by: Cédric Le Goater [dwg: Fix crash in qtest case where spapr->irq_map can be NULL at the new assert()] Signed-off-by: David Gibson --- hw/ppc/spapr.c | 4 ---- hw/ppc/spapr_irq.c | 7 ++----- include/hw/ppc/spapr_irq.h | 1 - 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 51e1cb0d46..64fc2255cc 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1755,10 +1755,6 @@ static void spapr_machine_reset(MachineState *machine) ppc_set_compat(first_ppc_cpu, spapr->max_compat_pvr, &error_fatal); } - if (!SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) { - spapr_irq_msi_reset(spapr); - } - /* * This is fixing some of the default configuration of the XIVE * devices. To be called after the reset of the machine devices. diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 2f87fe08f3..06fe2432ba 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -59,11 +59,6 @@ void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num) bitmap_clear(spapr->irq_map, irq - SPAPR_IRQ_MSI, num); } -void spapr_irq_msi_reset(SpaprMachineState *spapr) -{ - bitmap_clear(spapr->irq_map, 0, spapr->irq_map_nr); -} - static void spapr_irq_init_kvm(SpaprMachineState *spapr, SpaprIrq *irq, Error **errp) { @@ -731,6 +726,8 @@ int spapr_irq_post_load(SpaprMachineState *spapr, int version_id) void spapr_irq_reset(SpaprMachineState *spapr, Error **errp) { + assert(!spapr->irq_map || bitmap_empty(spapr->irq_map, spapr->irq_map_nr)); + if (spapr->irq->reset) { spapr->irq->reset(spapr, errp); } diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index 8132e00366..5db305165c 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -30,7 +30,6 @@ 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); void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num); -void spapr_irq_msi_reset(SpaprMachineState *spapr); typedef struct SpaprIrq { uint32_t nr_irqs; From patchwork Wed Aug 21 07:25:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105861 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 AFDBD14F7 for ; Wed, 21 Aug 2019 07:51: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 85FE222DA7 for ; Wed, 21 Aug 2019 07:51: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="D+66zVAn" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 85FE222DA7 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]:44682 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LOi-0000qZ-CC for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:51:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42618) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0r-0005Bz-E2 for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0q-0008UL-48 for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:33 -0400 Received: from ozlabs.org ([203.11.71.1]:49305) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0p-00089v-82; Wed, 21 Aug 2019 03:26:32 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjF2C7Rz9sQy; Wed, 21 Aug 2019 17:25:51 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372353; bh=5NEgZKDdcOaJCDCiAi3qAZVToJWd/48Fn/4AGJJvmnI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=D+66zVAnbnU6cpgNsHZl/FTd9/pSzz+MYZMAwmIXgHOPhYP134ttrlI7zILO5tdxy OtJx5chAObPJ2w60MYeBfm0ozlJtPrJ02hcst4QhR+OVeKsxrG9T4spBNKDif8lg+v zaTn+ROwgsv4g8Ku9DV//rZr4o8FrtBlt+kWin+k= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:36 +1000 Message-Id: <20190821072542.23090-37-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 36/42] spapr: Implement better workaround in spapr-vty device 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, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, Paul Mackerras , qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Paul Mackerras Linux guest kernels have code which scans the string of characters returned from the H_GET_TERM_CHAR hypercall and removes any \0 character which comes immediately after a \r character. This is to work around a bug which was present in some ancient versions of PowerVM. In order to avoid the corruption of the console byte stream that this introduced, commit 6c3bc244d3cb ("spapr: Implement bug in spapr-vty device to be compatible with PowerVM") added a workaround which adds a \0 character after every \r character. Unfortunately, this corrupts the console byte stream for those operating systems, such as AIX, which don't remove the null bytes. We can avoid triggering the Linux kernel workaround if we avoid returning a buffer which contains a \0 after a \r. We can do that by breaking out of the loop in vty_getchars() if we are about to insert a \0 and the previous character in the buffer is a \r. That means we return the characters up to the \r for the current H_GET_TERM_CHAR, and the characters starting with the \0 for the next one. With this workaround, we don't insert any spurious characters and we avoid triggering the Linux kernel workaround, so the guest will receive an uncorrupted stream whether or not they have the workaround. Fixes: 6c3bc244d3cb ("spapr: Implement bug in spapr-vty device to be compatible with PowerVM") Signed-off-by: Paul Mackerras Message-Id: <20190731043653.shdi5sizjp4t65op@oak.ozlabs.ibm.com> Signed-off-by: David Gibson --- hw/char/spapr_vty.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c index 7f860fcce7..087c93e4fa 100644 --- a/hw/char/spapr_vty.c +++ b/hw/char/spapr_vty.c @@ -59,25 +59,19 @@ static int vty_getchars(SpaprVioDevice *sdev, uint8_t *buf, int max) int n = 0; while ((n < max) && (dev->out != dev->in)) { - buf[n++] = dev->buf[dev->out++ % VTERM_BUFSIZE]; - - /* PowerVM's vty implementation has a bug where it inserts a - * \0 after every \r going to the guest. Existing guests have - * a workaround for this which removes every \0 immediately - * following a \r, so here we make ourselves bug-for-bug - * compatible, so that the guest won't drop a real \0-after-\r - * that happens to occur in a binary stream. */ - if (buf[n - 1] == '\r') { - if (n < max) { - buf[n++] = '\0'; - } else { - /* No room for the extra \0, roll back and try again - * next time */ - dev->out--; - n--; - break; - } + /* + * Long ago, PowerVM's vty implementation had a bug where it + * inserted a \0 after every \r going to the guest. Existing + * guests have a workaround for this which removes every \0 + * immediately following a \r. To avoid triggering this + * workaround, we stop before inserting a \0 if the preceding + * character in the output buffer is a \r. + */ + if (n > 0 && (buf[n - 1] == '\r') && + (dev->buf[dev->out % VTERM_BUFSIZE] == '\0')) { + break; } + buf[n++] = dev->buf[dev->out++ % VTERM_BUFSIZE]; } qemu_chr_fe_accept_input(&dev->chardev); From patchwork Wed Aug 21 07:25:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105831 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 7013D912 for ; Wed, 21 Aug 2019 07:40:34 +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 480282339F for ; Wed, 21 Aug 2019 07:40:34 +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="Sm60RcjA" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 480282339F 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]:44552 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LEO-0004j1-UM for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:40:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42575) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0p-0005BZ-8m for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0o-0008Rx-78 for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:31 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:49413) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0m-00086q-VY; Wed, 21 Aug 2019 03:26:30 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjD0r0wz9sR0; Wed, 21 Aug 2019 17:25:51 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372352; bh=z0xLOJT+W0eOPaWM+bo1X3aSAUKo9hpukkRVyqWQD+Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Sm60RcjAEGETDAjtFDRGsRk/m4wVjcFsfZxKeQxpLs8rl91afDDiI6MIS7jtsHROj aNhbi9xj8hPvE0o1vLIzGNQ0Rrh6V2bIsmGWafAH7YfBRHR8Tn5+Ql/V0p8f5WQjvY y8aAuMp4Ed6ufDIv6QJkMTdkOt6+lBYpKJ8fOvac= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:37 +1000 Message-Id: <20190821072542.23090-38-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 37/42] spapr/xive: Mask the EAS when allocating an IRQ 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, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, =?utf-8?q?C=C3=A9dric_Le_Goater?= , Satheesh Rajendran , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater If an IRQ is allocated and not configured, such as a MSI requested by a PCI driver, it can be saved in its default state and possibly later on restored using the same state. If not initially MASKED, KVM will try to find a matching priority/target tuple for the interrupt and fail to restore the VM because 0/0 is not a valid target. When allocating a IRQ number, the EAS should be set to a sane default : VALID and MASKED. Reported-by: Satheesh Rajendran Signed-off-by: Cédric Le Goater Message-Id: <20190813164420.9829-1-clg@kaod.org> Signed-off-by: David Gibson --- hw/intc/spapr_xive.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index a29b48edf7..c1c97192a7 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -536,7 +536,10 @@ bool spapr_xive_irq_claim(SpaprXive *xive, uint32_t lisn, bool lsi) return false; } - xive->eat[lisn].w |= cpu_to_be64(EAS_VALID); + /* + * 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); } From patchwork Wed Aug 21 07:25:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105865 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 77B8814F7 for ; Wed, 21 Aug 2019 07:53:11 +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 48C9F2332A for ; Wed, 21 Aug 2019 07:53:11 +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="k1JMFcPW" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 48C9F2332A 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]:44718 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LQc-0003nb-97 for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:53:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42615) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L0r-0005By-7j for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L0q-0008UK-3m for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:33 -0400 Received: from ozlabs.org ([203.11.71.1]:33781) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L0p-0008BV-NP; Wed, 21 Aug 2019 03:26:32 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjF4BGcz9sRD; Wed, 21 Aug 2019 17:25:51 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372353; bh=6GY9++/Hv1KppOVgXUV+rDcGBLJtsjsXR/b4Qa8ecqI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=k1JMFcPWQRQwEf/bcGe7LEaPA3b2+wWqHLXrD6PXtZvEzy3seq85zXthhPV5D8N5x 5ZY99VWTBfEo3YkcVgXlqmfgIOudzLB4seAOe8zdj/kelx2TXhXdZvkaUleDwwyY33 nF8tar15+srUojPhvwj5/khp/lTTgKRozF8ihMfU= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:38 +1000 Message-Id: <20190821072542.23090-39-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 38/42] target/ppc: Add Directed Privileged Door-bell Exception State (DPDES) SPR 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, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Alexey Kardashevskiy DPDES stores a status of a doorbell message and if it is lost in migration, the destination CPU won't receive it. This does not hit us much as IPIs complete too quick to catch a pending one and even if we missed one, broadcasts happen often enough to wake that CPU. This defines DPDES and registers with KVM for migration. Signed-off-by: Alexey Kardashevskiy Message-Id: <20190816061733.53572-1-aik@ozlabs.ru> Signed-off-by: David Gibson --- target/ppc/cpu.h | 1 + target/ppc/translate_init.inc.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 50245a8c4d..4b35c8e4f4 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1466,6 +1466,7 @@ typedef PowerPCCPU ArchCPU; #define SPR_MPC_ICTRL (0x09E) #define SPR_MPC_BAR (0x09F) #define SPR_PSPB (0x09F) +#define SPR_DPDES (0x0B0) #define SPR_DAWR (0x0B4) #define SPR_RPR (0x0BA) #define SPR_CIABR (0x0BB) diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index c9fcd87095..7e41ae1456 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -8198,6 +8198,18 @@ static void gen_spr_power8_pspb(CPUPPCState *env) KVM_REG_PPC_PSPB, 0); } +static void gen_spr_power8_dpdes(CPUPPCState *env) +{ +#if !defined(CONFIG_USER_ONLY) + /* Directed Privileged Door-bell Exception State, used for IPI */ + spr_register_kvm_hv(env, SPR_DPDES, "DPDES", + SPR_NOACCESS, SPR_NOACCESS, + &spr_read_generic, SPR_NOACCESS, + &spr_read_generic, &spr_write_generic, + KVM_REG_PPC_DPDES, 0x00000000); +#endif +} + static void gen_spr_power8_ic(CPUPPCState *env) { #if !defined(CONFIG_USER_ONLY) @@ -8629,6 +8641,7 @@ static void init_proc_POWER8(CPUPPCState *env) gen_spr_power8_pmu_user(env); gen_spr_power8_tm(env); gen_spr_power8_pspb(env); + gen_spr_power8_dpdes(env); gen_spr_vtb(env); gen_spr_power8_ic(env); gen_spr_power8_book4(env); @@ -8817,6 +8830,7 @@ static void init_proc_POWER9(CPUPPCState *env) gen_spr_power8_pmu_user(env); gen_spr_power8_tm(env); gen_spr_power8_pspb(env); + gen_spr_power8_dpdes(env); gen_spr_vtb(env); gen_spr_power8_ic(env); gen_spr_power8_book4(env); From patchwork Wed Aug 21 07:25:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105975 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 C560E13B1 for ; Wed, 21 Aug 2019 08:07: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 9982F2332A for ; Wed, 21 Aug 2019 08:07: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="Id8/Z6qx" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9982F2332A 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]:44898 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0Lej-0005a4-Rs for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 04:07:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43046) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L1a-0006AG-61 for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:27:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L1Y-0000Ug-IN for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:27:18 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:35097) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L1X-0000FZ-TR; Wed, 21 Aug 2019 03:27:16 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjH3MCTz9sRK; Wed, 21 Aug 2019 17:25:52 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372355; bh=zJX1WYNT6gpp6KhwS3tqKkTcR3wZv/KDIUPLufTIcRk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Id8/Z6qxeqARbrFa8uRP+reOWdoUZdUDkPfRnHKm/SVQn0DrifE2AkbCNlHnonsh9 bIFmlcucLHLR9j1RMzZFiwVjTkdAV08UBG71/ybLCO9qWfcwdfUxZ9i2PWGQ9fugJV tINr+Lc0HSrUtZPzkRTSWjXa+KbtJ19XrKeNfyhA= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:39 +1000 Message-Id: <20190821072542.23090-40-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 39/42] ppc: Add support for 'mffsl' instruction 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, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, "Paul A. Clarke" , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: "Paul A. Clarke" ISA 3.0B added a set of Floating-Point Status and Control Register (FPSCR) instructions: mffsce, mffscdrn, mffscdrni, mffscrn, mffscrni, mffsl. This patch adds support for 'mffsl'. 'mffsl' is identical to 'mffs', except it only returns mode, status, and enable bits from the FPSCR. On CPUs without support for 'mffsl' (below ISA 3.0), the 'mffsl' instruction will execute identically to 'mffs'. Note: I renamed FPSCR_RN to FPSCR_RN0 so I could create an FPSCR_RN mask which is both bits of the FPSCR rounding mode, as defined in the ISA. I also fixed a typo in the definition of FPSCR_FR. Signed-off-by: Paul A. Clarke v4: - nit: added some braces to resolve a checkpatch complaint. v3: - Changed tcg_gen_and_i64 to tcg_gen_andi_i64, eliminating the need for a temporary, per review from Richard Henderson. v2: - I found that I copied too much of the 'mffs' implementation. The 'Rc' condition code bits are not needed for 'mffsl'. Removed. - I now free the (renamed) 'tmask' temporary. - I now bail early for older ISA to the original 'mffs' implementation. Message-Id: <1565982203-11048-1-git-send-email-pc@us.ibm.com> Signed-off-by: David Gibson --- disas/ppc.c | 5 +++++ target/ppc/cpu.h | 15 ++++++++++----- target/ppc/fpu_helper.c | 4 ++-- target/ppc/translate/fp-impl.inc.c | 22 ++++++++++++++++++++++ target/ppc/translate/fp-ops.inc.c | 4 +++- 5 files changed, 42 insertions(+), 8 deletions(-) diff --git a/disas/ppc.c b/disas/ppc.c index a545437de9..63e97cfe1d 100644 --- a/disas/ppc.c +++ b/disas/ppc.c @@ -1765,6 +1765,9 @@ extract_tbr (unsigned long insn, /* An X_MASK with the RA and RB fields fixed. */ #define XRARB_MASK (X_MASK | RA_MASK | RB_MASK) +/* An X form instruction with the RA field fixed. */ +#define XRA(op, xop, ra) (X((op), (xop)) | (((ra) << 16) & XRA_MASK)) + /* An XRARB_MASK, but with the L bit clear. */ #define XRLARB_MASK (XRARB_MASK & ~((unsigned long) 1 << 16)) @@ -4998,6 +5001,8 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "ddivq", XRC(63,546,0), X_MASK, POWER6, { FRT, FRA, FRB } }, { "ddivq.", XRC(63,546,1), X_MASK, POWER6, { FRT, FRA, FRB } }, +{ "mffsl", XRA(63,583,12), XRARB_MASK, POWER9, { FRT } }, + { "mffs", XRC(63,583,0), XRARB_MASK, COM, { FRT } }, { "mffs.", XRC(63,583,1), XRARB_MASK, COM, { FRT } }, diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 4b35c8e4f4..eaee1a5575 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -591,7 +591,7 @@ enum { #define FPSCR_XE 3 /* Floating-point inexact exception enable */ #define FPSCR_NI 2 /* Floating-point non-IEEE mode */ #define FPSCR_RN1 1 -#define FPSCR_RN 0 /* Floating-point rounding control */ +#define FPSCR_RN0 0 /* Floating-point rounding control */ #define fpscr_fex (((env->fpscr) >> FPSCR_FEX) & 0x1) #define fpscr_vx (((env->fpscr) >> FPSCR_VX) & 0x1) #define fpscr_ox (((env->fpscr) >> FPSCR_OX) & 0x1) @@ -614,7 +614,7 @@ enum { #define fpscr_ze (((env->fpscr) >> FPSCR_ZE) & 0x1) #define fpscr_xe (((env->fpscr) >> FPSCR_XE) & 0x1) #define fpscr_ni (((env->fpscr) >> FPSCR_NI) & 0x1) -#define fpscr_rn (((env->fpscr) >> FPSCR_RN) & 0x3) +#define fpscr_rn (((env->fpscr) >> FPSCR_RN0) & 0x3) /* Invalid operation exception summary */ #define fpscr_ix ((env->fpscr) & ((1 << FPSCR_VXSNAN) | (1 << FPSCR_VXISI) | \ (1 << FPSCR_VXIDI) | (1 << FPSCR_VXZDZ) | \ @@ -640,7 +640,7 @@ enum { #define FP_VXZDZ (1ull << FPSCR_VXZDZ) #define FP_VXIMZ (1ull << FPSCR_VXIMZ) #define FP_VXVC (1ull << FPSCR_VXVC) -#define FP_FR (1ull << FSPCR_FR) +#define FP_FR (1ull << FPSCR_FR) #define FP_FI (1ull << FPSCR_FI) #define FP_C (1ull << FPSCR_C) #define FP_FL (1ull << FPSCR_FL) @@ -648,7 +648,7 @@ enum { #define FP_FE (1ull << FPSCR_FE) #define FP_FU (1ull << FPSCR_FU) #define FP_FPCC (FP_FL | FP_FG | FP_FE | FP_FU) -#define FP_FPRF (FP_C | FP_FL | FP_FG | FP_FE | FP_FU) +#define FP_FPRF (FP_C | FP_FPCC) #define FP_VXSOFT (1ull << FPSCR_VXSOFT) #define FP_VXSQRT (1ull << FPSCR_VXSQRT) #define FP_VXCVI (1ull << FPSCR_VXCVI) @@ -659,7 +659,12 @@ enum { #define FP_XE (1ull << FPSCR_XE) #define FP_NI (1ull << FPSCR_NI) #define FP_RN1 (1ull << FPSCR_RN1) -#define FP_RN (1ull << FPSCR_RN) +#define FP_RN0 (1ull << FPSCR_RN0) +#define FP_RN (FP_RN1 | FP_RN0) + +#define FP_MODE FP_RN +#define FP_ENABLES (FP_VE | FP_OE | FP_UE | FP_ZE | FP_XE) +#define FP_STATUS (FP_FR | FP_FI | FP_FPRF) /* the exception bits which can be cleared by mcrfs - includes FX */ #define FP_EX_CLEAR_BITS (FP_FX | FP_OX | FP_UX | FP_ZX | \ diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index f437c88aad..5611cf0156 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -403,7 +403,7 @@ void helper_fpscr_clrbit(CPUPPCState *env, uint32_t bit) if (prev == 1) { switch (bit) { case FPSCR_RN1: - case FPSCR_RN: + case FPSCR_RN0: fpscr_set_rounding_mode(env); break; case FPSCR_VXSNAN: @@ -557,7 +557,7 @@ void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit) } break; case FPSCR_RN1: - case FPSCR_RN: + case FPSCR_RN0: fpscr_set_rounding_mode(env); break; default: diff --git a/target/ppc/translate/fp-impl.inc.c b/target/ppc/translate/fp-impl.inc.c index 9dcff947c0..7cd9d8db05 100644 --- a/target/ppc/translate/fp-impl.inc.c +++ b/target/ppc/translate/fp-impl.inc.c @@ -617,6 +617,28 @@ static void gen_mffs(DisasContext *ctx) tcg_temp_free_i64(t0); } +/* mffsl */ +static void gen_mffsl(DisasContext *ctx) +{ + TCGv_i64 t0; + + if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) { + return gen_mffs(ctx); + } + + if (unlikely(!ctx->fpu_enabled)) { + gen_exception(ctx, POWERPC_EXCP_FPU); + return; + } + t0 = tcg_temp_new_i64(); + gen_reset_fpstatus(); + tcg_gen_extu_tl_i64(t0, cpu_fpscr); + /* Mask everything except mode, status, and enables. */ + tcg_gen_andi_i64(t0, t0, FP_MODE | FP_STATUS | FP_ENABLES); + set_fpr(rD(ctx->opcode), t0); + tcg_temp_free_i64(t0); +} + /* mtfsb0 */ static void gen_mtfsb0(DisasContext *ctx) { diff --git a/target/ppc/translate/fp-ops.inc.c b/target/ppc/translate/fp-ops.inc.c index 621f6bfe0c..88ebc2526c 100644 --- a/target/ppc/translate/fp-ops.inc.c +++ b/target/ppc/translate/fp-ops.inc.c @@ -104,7 +104,9 @@ GEN_HANDLER_E(fcpsgn, 0x3F, 0x08, 0x00, 0x00000000, PPC_NONE, PPC2_ISA205), GEN_HANDLER_E(fmrgew, 0x3F, 0x06, 0x1E, 0x00000001, PPC_NONE, PPC2_VSX207), GEN_HANDLER_E(fmrgow, 0x3F, 0x06, 0x1A, 0x00000001, PPC_NONE, PPC2_VSX207), GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT), -GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT), +GEN_HANDLER_E_2(mffs, 0x3F, 0x07, 0x12, 0x00, 0x00000000, PPC_FLOAT, PPC_NONE), +GEN_HANDLER_E_2(mffsl, 0x3F, 0x07, 0x12, 0x18, 0x00000000, PPC_FLOAT, + PPC2_ISA300), GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT), GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT), GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00000000, PPC_FLOAT), From patchwork Wed Aug 21 07:25:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105959 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 BFD8D912 for ; Wed, 21 Aug 2019 08:02:22 +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 9589F22D6D for ; Wed, 21 Aug 2019 08:02: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="A3Il0kCb" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9589F22D6D 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]:44816 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LZV-0007aP-7P for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 04:02:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42943) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L1H-0005hI-Dn for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:27:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L1F-0000Kq-Ru for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:59 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:53327) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L1F-00005E-EU; Wed, 21 Aug 2019 03:26:57 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjH26Wsz9sRM; Wed, 21 Aug 2019 17:25:52 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372355; bh=jK/ciQJoSLXGmTAlQkkkT7mytfHoAHk++6GYWm8bOaA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=A3Il0kCbHGwp+6xoHS3g0Zcn0KLkFjwNWTyIPsjuDej0cEsvtUqRAwMaY7DB5+APh U8pvbZv5+tPkWSU7pyDR6lcn7otMNwQmSrn5YldI28hWW3w0HdqLT6KlFh5DG5PWP0 u04uWid690q79Nphe3NEcwQBdwHUkt4TmCx0HIJQ= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:40 +1000 Message-Id: <20190821072542.23090-41-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 40/42] ppc: conform to processor User's Manual for xscvdpspn 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, aik@ozlabs.ru, qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, "Paul A. Clarke" , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: "Paul A. Clarke" The POWER8 and POWER9 User's Manuals specify the implementation behavior for what the ISA leaves "undefined" behavior for the xscvdpspn and xscvdpsp instructions. This patch corrects the QEMU implementation to match the hardware implementation for that case. ISA 3.0B has xscvdpspn leaving its result in word 0 of the target register, with the other words of the target register left "undefined". The User's Manuals specify: VSX scalar convert from double-precision to single-precision (xscvdpsp, xscvdpspn). VSR[32:63] is set to VSR[0:31]. So, words 0 and 1 both contain the result. Note: this is important because GCC as of version 8 or so, assumes and takes advantage of this behavior to optimize the following sequence: xscvdpspn vs0,vs1 mffprwz r8,f0 ISA 3.0B has xscvdpspn leaving its result in word 0 of the target register, and mffprwz expecting its input to come from word 1 of the source register. This sequence fails with QEMU, as a shift is required between those two instructions. However, since the hardware splats the result to both words 0 and 1 of its output register, the shift is not necessary. Expect a future revision of the ISA to specify this behavior. Signed-off-by: Paul A. Clarke v2 - Splitting patch "ppc: Three floating point fixes"; this is just one part. - Updated commit message to clarify behavior is documented in User's Manuals. - Updated commit message to correct which words are in output and source of xscvdpspn and mffprz. - No source changes to this part of the original patch. Message-Id: <1566236601-22954-1-git-send-email-pc@us.ibm.com> Signed-off-by: David Gibson --- target/ppc/fpu_helper.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index 5611cf0156..23b9c97439 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -2871,10 +2871,14 @@ void helper_xscvqpdp(CPUPPCState *env, uint32_t opcode, uint64_t helper_xscvdpspn(CPUPPCState *env, uint64_t xb) { + uint64_t result; + float_status tstat = env->fp_status; set_float_exception_flags(0, &tstat); - return (uint64_t)float64_to_float32(xb, &tstat) << 32; + result = (uint64_t)float64_to_float32(xb, &tstat); + /* hardware replicates result to both words of the doubleword result. */ + return (result << 32) | result; } uint64_t helper_xscvspdpn(CPUPPCState *env, uint64_t xb) From patchwork Wed Aug 21 07:25:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105849 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 192831813 for ; Wed, 21 Aug 2019 07:47:42 +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 E46B32339F for ; Wed, 21 Aug 2019 07:47:41 +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="Onds5MDI" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E46B32339F 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]:44632 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LLI-0005EO-DM for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:47:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42880) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L1F-0005dT-2R for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L1D-0000HU-Ou for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:56 -0400 Received: from ozlabs.org ([203.11.71.1]:41471) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L1D-0000FX-DV; Wed, 21 Aug 2019 03:26:55 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjH563Yz9sRJ; Wed, 21 Aug 2019 17:25:52 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372355; bh=LBLOm9mkU3pspBTmFyXrCZgMP0BWYNROIiCcVmX9xdo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Onds5MDIWLIR+JZjWNuPMM2aZVmrb9DaNjvWQ6husp3AfaCXb9rXwgugzfVwD33gK pJTrUnlkjGsFzbCb6xkuKL612g7g5x2NwEIN7fWY/75X3CHYHmKsaMXrj8X/ciFy+a +mZPIekN3jgxvbhdShG9ohuegXNfNfxArbejVRMA= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:41 +1000 Message-Id: <20190821072542.23090-42-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PULL 41/42] ppc: Fix emulated INFINITY and NAN conversions 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, aik@ozlabs.ru, Richard Henderson , qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, "Paul A. Clarke" , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: "Paul A. Clarke" helper_todouble() was not properly converting INFINITY from 32 bit float to 64 bit double. (Normalized operand conversion is unchanged, other than indentation.) Signed-off-by: Paul A. Clarke Message-Id: <1566242388-9244-1-git-send-email-pc@us.ibm.com> Reviewed-by: Richard Henderson Signed-off-by: David Gibson --- target/ppc/fpu_helper.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index 23b9c97439..52bcda27a6 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -58,10 +58,17 @@ uint64_t helper_todouble(uint32_t arg) uint64_t ret; if (likely(abs_arg >= 0x00800000)) { - /* Normalized operand, or Inf, or NaN. */ - ret = (uint64_t)extract32(arg, 30, 2) << 62; - ret |= ((extract32(arg, 30, 1) ^ 1) * (uint64_t)7) << 59; - ret |= (uint64_t)extract32(arg, 0, 30) << 29; + if (unlikely(extract32(arg, 23, 8) == 0xff)) { + /* Inf or NAN. */ + ret = (uint64_t)extract32(arg, 31, 1) << 63; + ret |= (uint64_t)0x7ff << 52; + ret |= (uint64_t)extract32(arg, 0, 23) << 29; + } else { + /* Normalized operand. */ + ret = (uint64_t)extract32(arg, 30, 2) << 62; + ret |= ((extract32(arg, 30, 1) ^ 1) * (uint64_t)7) << 59; + ret |= (uint64_t)extract32(arg, 0, 30) << 29; + } } else { /* Zero or Denormalized operand. */ ret = (uint64_t)extract32(arg, 31, 1) << 63; From patchwork Wed Aug 21 07:25:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 11105949 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 8369A13A4 for ; Wed, 21 Aug 2019 07:58:17 +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 5A7A522D6D for ; Wed, 21 Aug 2019 07:58:17 +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="gmuS3eI1" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 5A7A522D6D 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]:44762 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0LVY-0001X0-8K for patchwork-qemu-devel@patchwork.kernel.org; Wed, 21 Aug 2019 03:58:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:42882) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i0L1F-0005do-7u for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i0L1E-0000Hx-1j for qemu-devel@nongnu.org; Wed, 21 Aug 2019 03:26:57 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:55877) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i0L1D-0008WF-KT; Wed, 21 Aug 2019 03:26:55 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 46CzjH0frgz9sR6; Wed, 21 Aug 2019 17:25:52 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1566372355; bh=09s3Sx5x9dItVKpkAhqcWtlr41w7mRGKr2ii2x7SWlc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gmuS3eI1p63ubtJ5yo2a1NHuAh2EYkDTZzZE2Z7EuNsu8dOBd+oOPGDWyg0zyOemG k/Oqc/lossuzOzdbd457fvu/xHMbkJxA0hysJbVT4PtkRYvfv3FqHYcdg0jaGppAhu No4rR3WVrN9uPtQm1+qjekeNwLYkFY2qk4kifgpw= From: David Gibson To: peter.maydell@linaro.org Date: Wed, 21 Aug 2019 17:25:42 +1000 Message-Id: <20190821072542.23090-43-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821072542.23090-1-david@gibson.dropbear.id.au> References: <20190821072542.23090-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 Subject: [Qemu-devel] [PULL 42/42] ppc: Fix emulated single to double denormalized conversions 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, aik@ozlabs.ru, Richard Henderson , qemu-devel@nongnu.org, groug@kaod.org, qemu-ppc@nongnu.org, "Paul A. Clarke" , David Gibson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: "Paul A. Clarke" helper_todouble() was not properly converting any denormalized 32 bit float to 64 bit double. Fix-suggested-by: Richard Henderson Signed-off-by: Paul A. Clarke v2: - Splitting patch "ppc: Three floating point fixes"; this is just one part. - Original suggested "fix" was likely flawed. v2 is rewritten by Richard Henderson (Thanks, Richard!); I reformatted the comments in a couple of places, compiled, and tested. Message-Id: <1566250936-14538-1-git-send-email-pc@us.ibm.com> Signed-off-by: David Gibson --- target/ppc/fpu_helper.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index 52bcda27a6..07bc9051b0 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -73,11 +73,20 @@ uint64_t helper_todouble(uint32_t arg) /* Zero or Denormalized operand. */ ret = (uint64_t)extract32(arg, 31, 1) << 63; if (unlikely(abs_arg != 0)) { - /* Denormalized operand. */ - int shift = clz32(abs_arg) - 9; - int exp = -126 - shift + 1023; + /* + * Denormalized operand. + * Shift fraction so that the msb is in the implicit bit position. + * Thus, shift is in the range [1:23]. + */ + int shift = clz32(abs_arg) - 8; + /* + * The first 3 terms compute the float64 exponent. We then bias + * this result by -1 so that we can swallow the implicit bit below. + */ + int exp = -126 - shift + 1023 - 1; + ret |= (uint64_t)exp << 52; - ret |= abs_arg << (shift + 29); + ret += (uint64_t)abs_arg << (52 - 23 + shift); } } return ret;