Received: by 2002:a05:6a10:9e8c:0:0:0:0 with SMTP id y12csp395222pxx; Wed, 28 Oct 2020 07:24:50 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyrb3+CKuuGdo+vZYBTeueXPTyXCpH9B+sJaHf8wnn/8dWXZisbDiZfGJJ2gUULjOPZZsMB X-Received: by 2002:a50:fd17:: with SMTP id i23mr7612352eds.50.1603895090090; Wed, 28 Oct 2020 07:24:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1603895090; cv=none; d=google.com; s=arc-20160816; b=j2kQwDfnbu4005mxV+A9X3kQjnXGA0DF6tkq/vaxheWOtQ9w8P3Zh2DWZZEuAZPUKI R8GGMt0HDdW5phCrlaczTR1XebAQUMxPszOum/WtmgHmYRD0CJ7arVFeBzOZDrCHGiLC po6uKRm+JEf1HFr4uOt2famg43/1ahUj1FN6GtuyLq7w0LmZy1RiZfzQtuCi0bjSfnQh qfTRkIDtV+mx0SutrXW0oGzCMBQ7Qh412G8iwZMTfQJOVTdFeQOcFYrZmz8p6Wlman7n MESZv8ozHRMlRQ6Yk5SqnysAR4lgvcULYJwUv9GvrYKOcSQ0j8/OYVGpCt8vVyBP5dWA koRw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=V/Qw0G5Y/idrxThfFnsUOHSCgc9EoN3xl+uUAlRunmk=; b=mQQeAAwHMBpTBzrD4nijclXl45mNHwCpB45kQiwKcWEYKxgCjH3dq7ISuBd2R5yMN7 BBa8GcwmuR+0IA/gIPmxYjeQXsq7isMY+By2gWQZQiE3jX2pP+vxKDWNdNiljggw9VKY C2KFVhP+OMJz+BK45MKKHEXG+VEM5j+pm5L1y7z76jeo0Sh+gLcXZbdnoE0o2YiSCVjj uJirQHH/8BOMlkfFbfTsPVgdJvjQRyAWCk/NrU0Jy0ddrXZligA2A+xTZCcE2h9yZv/i zIXaSDxxQIj8VhB9bkTug2pnCRI5bLYCM6gXMub2RztXgY8Ecdaut0pooN/YM+NeqD2z 65hw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=CVgLkYP1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id bs17si3022913ejb.543.2020.10.28.07.24.28; Wed, 28 Oct 2020 07:24:50 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=CVgLkYP1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1805497AbgJ0QAy (ORCPT + 99 others); Tue, 27 Oct 2020 12:00:54 -0400 Received: from mail.kernel.org ([198.145.29.99]:60430 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1801356AbgJ0Pks (ORCPT ); Tue, 27 Oct 2020 11:40:48 -0400 Received: from localhost (83-86-74-64.cable.dynamic.v4.ziggo.nl [83.86.74.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 1B58A223B0; Tue, 27 Oct 2020 15:40:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1603813247; bh=bRa3DKGN75xJX+mpwXYHr6yuiZ8lIsqRuOaC0aBISJo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CVgLkYP1sON9wSG1fj39E4td7CtW3fEW2WbZaaBRjAwO4Kndi60ZlR5HtiwijbHCh CaOAiyQ9sq6ivkpkoUKpZ11td799rsGfa86IGVbm8K1soj56Lvy6wkKcrzIP2hZwKs NRps6lypjzUZlR0CJB/XXuHmPgJda26qyx0eTTo8= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Nicholas Piggin , Michael Ellerman , Sasha Levin Subject: [PATCH 5.9 488/757] powerpc/security: Fix link stack flush instruction Date: Tue, 27 Oct 2020 14:52:18 +0100 Message-Id: <20201027135513.364884497@linuxfoundation.org> X-Mailer: git-send-email 2.29.1 In-Reply-To: <20201027135450.497324313@linuxfoundation.org> References: <20201027135450.497324313@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Nicholas Piggin [ Upstream commit 792254a77201453d9a77479e63dc216ad90462d2 ] The inline execution path for the hardware assisted branch flush instruction failed to set CTR to the correct value before bcctr, causing a crash when the feature is enabled. Fixes: 4d24e21cc694 ("powerpc/security: Allow for processors that flush the link stack using the special bcctr") Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20201007080605.64423-1-npiggin@gmail.com Signed-off-by: Sasha Levin --- arch/powerpc/include/asm/asm-prototypes.h | 4 ++- arch/powerpc/kernel/entry_64.S | 8 ++++-- arch/powerpc/kernel/security.c | 34 ++++++++++++++++------- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/include/asm/asm-prototypes.h b/arch/powerpc/include/asm/asm-prototypes.h index de14b1a34d568..9652756b0694c 100644 --- a/arch/powerpc/include/asm/asm-prototypes.h +++ b/arch/powerpc/include/asm/asm-prototypes.h @@ -144,7 +144,9 @@ void _kvmppc_restore_tm_pr(struct kvm_vcpu *vcpu, u64 guest_msr); void _kvmppc_save_tm_pr(struct kvm_vcpu *vcpu, u64 guest_msr); /* Patch sites */ -extern s32 patch__call_flush_branch_caches; +extern s32 patch__call_flush_branch_caches1; +extern s32 patch__call_flush_branch_caches2; +extern s32 patch__call_flush_branch_caches3; extern s32 patch__flush_count_cache_return; extern s32 patch__flush_link_stack_return; extern s32 patch__call_kvm_flush_link_stack; diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 733e40eba4ebe..2f3846192ec7d 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -430,7 +430,11 @@ _ASM_NOKPROBE_SYMBOL(save_nvgprs); #define FLUSH_COUNT_CACHE \ 1: nop; \ - patch_site 1b, patch__call_flush_branch_caches + patch_site 1b, patch__call_flush_branch_caches1; \ +1: nop; \ + patch_site 1b, patch__call_flush_branch_caches2; \ +1: nop; \ + patch_site 1b, patch__call_flush_branch_caches3 .macro nops number .rept \number @@ -512,7 +516,7 @@ _GLOBAL(_switch) kuap_check_amr r9, r10 - FLUSH_COUNT_CACHE + FLUSH_COUNT_CACHE /* Clobbers r9, ctr */ /* * On SMP kernels, care must be taken because a task may be diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c index c9876aab31421..e4e1a94ccf6a6 100644 --- a/arch/powerpc/kernel/security.c +++ b/arch/powerpc/kernel/security.c @@ -430,30 +430,44 @@ device_initcall(stf_barrier_debugfs_init); static void update_branch_cache_flush(void) { + u32 *site; + #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE + site = &patch__call_kvm_flush_link_stack; // This controls the branch from guest_exit_cont to kvm_flush_link_stack if (link_stack_flush_type == BRANCH_CACHE_FLUSH_NONE) { - patch_instruction_site(&patch__call_kvm_flush_link_stack, - ppc_inst(PPC_INST_NOP)); + patch_instruction_site(site, ppc_inst(PPC_INST_NOP)); } else { // Could use HW flush, but that could also flush count cache - patch_branch_site(&patch__call_kvm_flush_link_stack, - (u64)&kvm_flush_link_stack, BRANCH_SET_LINK); + patch_branch_site(site, (u64)&kvm_flush_link_stack, BRANCH_SET_LINK); } #endif + // Patch out the bcctr first, then nop the rest + site = &patch__call_flush_branch_caches3; + patch_instruction_site(site, ppc_inst(PPC_INST_NOP)); + site = &patch__call_flush_branch_caches2; + patch_instruction_site(site, ppc_inst(PPC_INST_NOP)); + site = &patch__call_flush_branch_caches1; + patch_instruction_site(site, ppc_inst(PPC_INST_NOP)); + // This controls the branch from _switch to flush_branch_caches if (count_cache_flush_type == BRANCH_CACHE_FLUSH_NONE && link_stack_flush_type == BRANCH_CACHE_FLUSH_NONE) { - patch_instruction_site(&patch__call_flush_branch_caches, - ppc_inst(PPC_INST_NOP)); + // Nothing to be done + } else if (count_cache_flush_type == BRANCH_CACHE_FLUSH_HW && link_stack_flush_type == BRANCH_CACHE_FLUSH_HW) { - patch_instruction_site(&patch__call_flush_branch_caches, - ppc_inst(PPC_INST_BCCTR_FLUSH)); + // Patch in the bcctr last + site = &patch__call_flush_branch_caches1; + patch_instruction_site(site, ppc_inst(0x39207fff)); // li r9,0x7fff + site = &patch__call_flush_branch_caches2; + patch_instruction_site(site, ppc_inst(0x7d2903a6)); // mtctr r9 + site = &patch__call_flush_branch_caches3; + patch_instruction_site(site, ppc_inst(PPC_INST_BCCTR_FLUSH)); + } else { - patch_branch_site(&patch__call_flush_branch_caches, - (u64)&flush_branch_caches, BRANCH_SET_LINK); + patch_branch_site(site, (u64)&flush_branch_caches, BRANCH_SET_LINK); // If we just need to flush the link stack, early return if (count_cache_flush_type == BRANCH_CACHE_FLUSH_NONE) { -- 2.25.1