From nobody Sat Jul 12 15:34:46 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1486014929939380.37187826544584; Wed, 1 Feb 2017 21:55:29 -0800 (PST) Received: from localhost ([::1]:54419 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cZAMh-0004af-OU for importer@patchew.org; Thu, 02 Feb 2017 00:55:27 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51515) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cZ9jp-0007Nc-SA for qemu-devel@nongnu.org; Thu, 02 Feb 2017 00:15:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cZ9jl-0003iq-LZ for qemu-devel@nongnu.org; Thu, 02 Feb 2017 00:15:17 -0500 Received: from ozlabs.org ([103.22.144.67]:42203) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cZ9jl-0003f3-4O; Thu, 02 Feb 2017 00:15:13 -0500 Received: by ozlabs.org (Postfix, from userid 1007) id 3vDSqQ3KWNz9s81; Thu, 2 Feb 2017 16:14:57 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1486012498; bh=y1Oyn/u8P2Rh0y5zWUFny9WQG/6Xc5uQt6mIAsCvA80=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BxI9UUT4UJZfw4CGQ1SQIjQq9Vv/w0WE+g1m76I4Qw4KgFQHhhLpsGxOBHqiVBlcY f9SP7o86lu6UQdtZshGd+zzH2zJEyXiiC5NVXkrCCMrCM4pKxzQofEdgkeck++CUEo pslkIJ2g0/qSQbkTHMmNyTByiZnQ4VFwUnW5jw48= From: David Gibson To: peter.maydell@linaro.org Date: Thu, 2 Feb 2017 16:13:34 +1100 Message-Id: <20170202051445.5735-37-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170202051445.5735-1-david@gibson.dropbear.id.au> References: <20170202051445.5735-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 103.22.144.67 Subject: [Qemu-devel] [PULL 036/107] ppc: Validate compatibility modes when setting X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, thuth@redhat.com, qemu-devel@nongnu.org, mdroth@linux.vnet.ibm.com, agraf@suse.de, aik@ozlabs.ru, qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Current ppc_set_compat() will attempt to set any compatiblity mode specified, regardless of whether it's available on the CPU. The caller is expected to make sure it is setting a possible mode, which is awkwward because most of the information to make that decision is at the CPU level. This begins to clean this up by introducing a ppc_check_compat() function which will determine if a given compatiblity mode is supported on a CPU (and also whether it lies within specified minimum and maximum compat levels, which will be useful later). It also contains an assertion that the CPU has a "virtual hypervisor"[1], that is, that the guest isn't permitted to execute hypervisor privilege code. Without that, the guest would own the PCR and so could override any mode set here. Only machine types which use a virtual hypervisor (i.e. 'pseries') should use ppc_check_compat(). ppc_set_compat() is modified to validate the compatibility mode it is given and fail if it's not available on this CPU. [1] Or user-only mode, which also obviously doesn't allow access to the hypervisor privileged PCR. We don't use that now, but could in future. Signed-off-by: David Gibson Reviewed-by: Alexey Kardashevskiy --- target/ppc/compat.c | 41 +++++++++++++++++++++++++++++++++++++++++ target/ppc/cpu.h | 2 ++ 2 files changed, 43 insertions(+) diff --git a/target/ppc/compat.c b/target/ppc/compat.c index 66529a6..1059555 100644 --- a/target/ppc/compat.c +++ b/target/ppc/compat.c @@ -28,29 +28,37 @@ typedef struct { uint32_t pvr; uint64_t pcr; + uint64_t pcr_level; int max_threads; } CompatInfo; =20 static const CompatInfo compat_table[] =3D { + /* + * Ordered from oldest to newest - the code relies on this + */ { /* POWER6, ISA2.05 */ .pvr =3D CPU_POWERPC_LOGICAL_2_05, .pcr =3D PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05 | PCR_TM_DIS | PCR_VSX_DIS, + .pcr_level =3D PCR_COMPAT_2_05, .max_threads =3D 2, }, { /* POWER7, ISA2.06 */ .pvr =3D CPU_POWERPC_LOGICAL_2_06, .pcr =3D PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_TM_DIS, + .pcr_level =3D PCR_COMPAT_2_06, .max_threads =3D 4, }, { .pvr =3D CPU_POWERPC_LOGICAL_2_06_PLUS, .pcr =3D PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_TM_DIS, + .pcr_level =3D PCR_COMPAT_2_06, .max_threads =3D 4, }, { /* POWER8, ISA2.07 */ .pvr =3D CPU_POWERPC_LOGICAL_2_07, .pcr =3D PCR_COMPAT_2_07, + .pcr_level =3D PCR_COMPAT_2_07, .max_threads =3D 8, }, }; @@ -67,6 +75,35 @@ static const CompatInfo *compat_by_pvr(uint32_t pvr) return NULL; } =20 +bool ppc_check_compat(PowerPCCPU *cpu, uint32_t compat_pvr, + uint32_t min_compat_pvr, uint32_t max_compat_pvr) +{ + PowerPCCPUClass *pcc =3D POWERPC_CPU_GET_CLASS(cpu); + const CompatInfo *compat =3D compat_by_pvr(compat_pvr); + const CompatInfo *min =3D compat_by_pvr(min_compat_pvr); + const CompatInfo *max =3D compat_by_pvr(max_compat_pvr); + +#if !defined(CONFIG_USER_ONLY) + g_assert(cpu->vhyp); +#endif + g_assert(!min_compat_pvr || min); + g_assert(!max_compat_pvr || max); + + if (!compat) { + /* Not a recognized logical PVR */ + return false; + } + if ((min && (compat < min)) || (max && (compat > max))) { + /* Outside specified range */ + return false; + } + if (!(pcc->pcr_supported & compat->pcr_level)) { + /* Not supported by this CPU */ + return false; + } + return true; +} + void ppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr, Error **errp) { const CompatInfo *compat =3D compat_by_pvr(compat_pvr); @@ -79,6 +116,10 @@ void ppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pv= r, Error **errp) } else if (!compat) { error_setg(errp, "Unknown compatibility PVR 0x%08"PRIx32, compat_p= vr); return; + } else if (!ppc_check_compat(cpu, compat_pvr, 0, 0)) { + error_setg(errp, "Compatibility PVR 0x%08"PRIx32" not valid for CP= U", + compat_pvr); + return; } else { pcr =3D compat->pcr; } diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index cd76053..22842dd 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1323,6 +1323,8 @@ static inline int cpu_mmu_index (CPUPPCState *env, bo= ol ifetch) =20 /* Compatibility modes */ #if defined(TARGET_PPC64) +bool ppc_check_compat(PowerPCCPU *cpu, uint32_t compat_pvr, + uint32_t min_compat_pvr, uint32_t max_compat_pvr); void ppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr, Error **errp); int ppc_compat_max_threads(PowerPCCPU *cpu); #endif /* defined(TARGET_PPC64) */ --=20 2.9.3