From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 87B8BC4742C for ; Fri, 13 Nov 2020 12:51:16 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 EFF5B20A8B for ; Fri, 13 Nov 2020 12:51:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Q+6J7Aov" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EFF5B20A8B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=arm.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=wx4nkD85oFDWSbZwd9wXPOqR1gLfVEAzCO1i66jAnc0=; b=Q+6J7Aovm+9VWC2/veVqjXrn2S q2Hye6DiIlzcsORpkVU2d8/UNec3ALnmTQcqAXaTQsc0pnqDbIAeXuHSsnECIqabeTRUrVCcmN9Rx A/PpBFkDthYvyU70NpT5ZpGEyT1YZocgFmHyjre1mcPbwl0hTTeFf/Px4dnNTO6bit633o0UNsWIc Ir9m7OY8sdeHqb5nsNpcWNFI8GeCnWftWSAHOxb5D5g+Dkq7w9EIymZLpRo4kuqQ6YIBgqgjk8Gg2 iwe9cod/Ccfn6aaHThb0YgseH6LQZmFSAlXuoUgyOPBxRUGLb/plNvisjYD6mez6zBnM8pTPM0Q/5 j9D1qJDg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kdYXM-0006U1-2F; Fri, 13 Nov 2020 12:50:44 +0000 Received: from foss.arm.com ([217.140.110.172]) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kdYWa-0006Cv-FR for linux-arm-kernel@lists.infradead.org; Fri, 13 Nov 2020 12:49:57 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 90932142F; Fri, 13 Nov 2020 04:49:55 -0800 (PST) Received: from lakrids.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com [10.121.207.14]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 91CBC3F6CF; Fri, 13 Nov 2020 04:49:54 -0800 (PST) From: Mark Rutland To: linux-arm-kernel@lists.infradead.org, catalin.marinas@arm.com, will@kernel.org Subject: [PATCHv4 07/17] arm64: sdei: explicitly simulate PAN/UAO entry Date: Fri, 13 Nov 2020 12:49:27 +0000 Message-Id: <20201113124937.20574-8-mark.rutland@arm.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20201113124937.20574-1-mark.rutland@arm.com> References: <20201113124937.20574-1-mark.rutland@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201113_074956_660890_FF6DC670 X-CRM114-Status: GOOD ( 19.15 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, robin.murphy@arm.com, james.morse@arm.com, hch@lst.de MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org SDEI enters the kernel with a non-architectural exception which does not manipulate PSTATE bits (e.g. PAN, UAO) in the same way as architectural exceptions. We currently fix this up with a combination of __uaccess_enable_hw_pan() and force_uaccess_access_begin(), but this has a few problems: * When set_fs() is removed, force_uaccess_begin() will have no HW side-effects, and UAO will need to be reset elsewhere. * Kernels built without support for PAN or UAO will not reset these bits upon SDEI entry, and may inherit the values used by a VM, leading to unexpected behaviour. * Kernels built *with* support for PAN or UAO, when run on systems with mismatched support across CPUs, will not reset these bits upon SDEI entry, and may inherit the values used by a VM, leading to unexpected behaviour. To deal with all of these, let's always explicitly reset the PAN and UAO bits when an SDEI event is delivered to the kernel. As above, we must do so even when the kernel has chosen to not use PAN/UAO, or was not built with support for PAN/UAO generally. The existing system_uses_ttbr0_pan() is redefined in terms of system_uses_hw_pan() both for clarity and as a minor optimization when HW PAN is not selected. Signed-off-by: Mark Rutland Cc: Catalin Marinas Cc: Christoph Hellwig Cc: James Morse Cc: Will Deacon --- arch/arm64/include/asm/cpufeature.h | 22 +++++++++++++++++++++- arch/arm64/kernel/sdei.c | 19 ++++++++++++++----- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index 97244d4feca9..98aab6138443 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -667,10 +667,16 @@ static __always_inline bool system_supports_fpsimd(void) return !cpus_have_const_cap(ARM64_HAS_NO_FPSIMD); } +static inline bool system_uses_hw_pan(void) +{ + return IS_ENABLED(CONFIG_ARM64_PAN) && + cpus_have_const_cap(ARM64_HAS_PAN); +} + static inline bool system_uses_ttbr0_pan(void) { return IS_ENABLED(CONFIG_ARM64_SW_TTBR0_PAN) && - !cpus_have_const_cap(ARM64_HAS_PAN); + !system_uses_hw_pan(); } static __always_inline bool system_supports_sve(void) @@ -762,6 +768,20 @@ static inline bool cpu_has_hw_af(void) ID_AA64MMFR1_HADBS_SHIFT); } +static inline bool cpu_has_pan(void) +{ + u64 mmfr1 = read_cpuid(ID_AA64MMFR1_EL1); + return cpuid_feature_extract_unsigned_field(mmfr1, + ID_AA64MMFR1_PAN_SHIFT); +} + +static inline bool cpu_has_uao(void) +{ + u64 mmfr2 = read_cpuid(ID_AA64MMFR2_EL1); + return cpuid_feature_extract_unsigned_field(mmfr2, + ID_AA64MMFR2_UAO_SHIFT); +} + #ifdef CONFIG_ARM64_AMU_EXTN /* Check whether the cpu supports the Activity Monitors Unit (AMU) */ extern bool cpu_has_amu_feat(int cpu); diff --git a/arch/arm64/kernel/sdei.c b/arch/arm64/kernel/sdei.c index 4a5f24602aa0..908d7be70eac 100644 --- a/arch/arm64/kernel/sdei.c +++ b/arch/arm64/kernel/sdei.c @@ -216,6 +216,16 @@ static __kprobes unsigned long _sdei_handler(struct pt_regs *regs, return vbar + 0x480; } +static void __kprobes notrace __sdei_pstate_entry(void) +{ + if (system_uses_hw_pan()) + set_pstate_pan(1); + else if (cpu_has_pan()) + set_pstate_pan(0); + + if (cpu_has_uao()) + set_pstate_uao(0); +} asmlinkage __kprobes notrace unsigned long __sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg) @@ -224,12 +234,11 @@ __sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg) mm_segment_t orig_addr_limit; /* - * We didn't take an exception to get here, so the HW hasn't set PAN or - * cleared UAO, and the exception entry code hasn't reset addr_limit. - * Set PAN, then use force_uaccess_begin() to clear UAO and reset - * addr_limit. + * We didn't take an exception to get here, so the HW hasn't + * set/cleared bits in PSTATE that we may rely on. Intialize PAN/UAO, + * then use force_uaccess_begin() to reset addr_limit. */ - __uaccess_enable_hw_pan(); + __sdei_pstate_entry(); orig_addr_limit = force_uaccess_begin(); nmi_enter(); -- 2.11.0 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel