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=-13.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,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 C3A8AC43461 for ; Fri, 11 Sep 2020 21:51:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6795C22208 for ; Fri, 11 Sep 2020 21:51:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1599861105; bh=6Y9FQy2gkr1wlQIry7m0Tr+ZJEYfl/keMal96M5+Co8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=NpN2UtOtb8cu+UnCBkiPn6DXK9jmDbIJnhLSnj0w9pdUSsin4Fg+vzw0qkFSXVQzY 7xqCIRTF9caILC6dwJ3w2L2mm6ORFLfjNTEVUtIZGSzoEhOuYGK+/qFHh5bJgJLsoR E2s2w2QA9HvRIgBJ340tbwSWWo434BB7jUOEObqs= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725905AbgIKVvl (ORCPT ); Fri, 11 Sep 2020 17:51:41 -0400 Received: from mail-io1-f68.google.com ([209.85.166.68]:35599 "EHLO mail-io1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725873AbgIKVvY (ORCPT ); Fri, 11 Sep 2020 17:51:24 -0400 Received: by mail-io1-f68.google.com with SMTP id r9so12665854ioa.2 for ; Fri, 11 Sep 2020 14:51:22 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Z9z3VR6zD4FpK2wX25Sr8AogKHA4TBLm2zvFT7kdd5s=; b=Exz8gV2y0lI/cYMrL377fkyDjGrNl59IjgexelFzX7oCQxLp7jAuWNJ4KaDFG4kmlo Zx+1g4MQbTA9+uILZPu/qXAmI0mRkF7CXpp5/KjGLyJA3H1DoZD2tI7PArHuxSgtFGsq o0rhSbMDinllCkgfUwtINy5urpIazrrgFYfMFE4ftMjuyV0gFDvIQmhIGA7akmLNU90x ot6pH+SrJ06daa87HN7Zs6IeDrfYv5HS+gCAl5j/Zzt+KN/lfHaGI6CVZhguyoIyjEzI eiBJ1CMYpWVpWmRMuylAwk6MIoSIYT4s6CpmdcWl5yrjQT8FFWO6TJQssG/iJPCSTND3 Vy2A== X-Gm-Message-State: AOAM533p673nf5xTqh/18pWwddf3AeCz1KtJoI0dDtaf9ZVJr9pzMXcm 5UuoSMyoxxdPwzIPZwgllw== X-Google-Smtp-Source: ABdhPJxQx+roCAKx4AnaIPIlqaXgWUyZqSxBkBNIXV9ppawnV7/t50T8OV2VivzabOEHQrk8gp6dLw== X-Received: by 2002:a02:4b07:: with SMTP id q7mr4008190jaa.84.1599861081813; Fri, 11 Sep 2020 14:51:21 -0700 (PDT) Received: from xps15.herring.priv ([64.188.179.251]) by smtp.googlemail.com with ESMTPSA id a20sm1927966ilq.57.2020.09.11.14.51.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Sep 2020 14:51:21 -0700 (PDT) From: Rob Herring To: Will Deacon , Catalin Marinas , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Jiri Olsa Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Alexander Shishkin , Namhyung Kim , Raphael Gault , Mark Rutland , Jonathan Cameron , Ian Rogers , honnappa.nagarahalli@arm.com Subject: [PATCH v3 01/10] arm64: pmu: Add hook to handle pmu-related undefined instructions Date: Fri, 11 Sep 2020 15:51:09 -0600 Message-Id: <20200911215118.2887710-2-robh@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200911215118.2887710-1-robh@kernel.org> References: <20200911215118.2887710-1-robh@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Raphael Gault This patch introduces a protection for the userspace processes which are trying to access the registers from the pmu registers on a big.LITTLE environment. It introduces a hook to handle undefined instructions. The goal here is to prevent the process to be interrupted by a signal when the error is caused by the task being scheduled while accessing a counter, causing the counter access to be invalid. As we are not able to know efficiently the number of counters available physically on both pmu in that context we consider that any faulting access to a counter which is architecturally correct should not cause a SIGILL signal if the permissions are set accordingly. This commit also modifies the mask of the mrs_hook declared in arch/arm64/kernel/cpufeatures.c which emulates only feature register access. This is necessary because this hook's mask was too large and thus masking any mrs instruction, even if not related to the emulated registers which made the pmu emulation inefficient. Signed-off-by: Raphael Gault Signed-off-by: Rob Herring --- v2: - Fix warning for set but unused sys_reg --- arch/arm64/kernel/cpufeature.c | 4 +-- arch/arm64/kernel/perf_event.c | 54 ++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index a389b999482e..00bf53ffd9b0 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -2811,8 +2811,8 @@ static int emulate_mrs(struct pt_regs *regs, u32 insn) } static struct undef_hook mrs_hook = { - .instr_mask = 0xfff00000, - .instr_val = 0xd5300000, + .instr_mask = 0xffff0000, + .instr_val = 0xd5380000, .pstate_mask = PSR_AA32_MODE_MASK, .pstate_val = PSR_MODE_EL0t, .fn = emulate_mrs, diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 462f9a9cc44b..70538ae684da 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -8,9 +8,11 @@ * This code is based heavily on the ARMv7 perf event code. */ +#include #include #include #include +#include #include #include @@ -1016,6 +1018,58 @@ static int armv8pmu_probe_pmu(struct arm_pmu *cpu_pmu) return probe.present ? 0 : -ENODEV; } +static int emulate_pmu(struct pt_regs *regs, u32 insn) +{ + u32 rt; + u32 pmuserenr; + + rt = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RT, insn); + pmuserenr = read_sysreg(pmuserenr_el0); + + if ((pmuserenr & (ARMV8_PMU_USERENR_ER|ARMV8_PMU_USERENR_CR)) != + (ARMV8_PMU_USERENR_ER|ARMV8_PMU_USERENR_CR)) + return -EINVAL; + + + /* + * Userspace is expected to only use this in the context of the scheme + * described in the struct perf_event_mmap_page comments. + * + * Given that context, we can only get here if we got migrated between + * getting the register index and doing the MSR read. This in turn + * implies we'll fail the sequence and retry, so any value returned is + * 'good', all we need is to be non-fatal. + * + * The choice of the value 0 is comming from the fact that when + * accessing a register which is not counting events but is accessible, + * we get 0. + */ + pt_regs_write_reg(regs, rt, 0); + + arm64_skip_faulting_instruction(regs, 4); + return 0; +} + +/* + * This hook will only be triggered by mrs + * instructions on PMU registers. This is mandatory + * in order to have a consistent behaviour even on + * big.LITTLE systems. + */ +static struct undef_hook pmu_hook = { + .instr_mask = 0xffff8800, + .instr_val = 0xd53b8800, + .fn = emulate_pmu, +}; + +static int __init enable_pmu_emulation(void) +{ + register_undef_hook(&pmu_hook); + return 0; +} + +core_initcall(enable_pmu_emulation); + static int armv8_pmu_init(struct arm_pmu *cpu_pmu, char *name, int (*map_event)(struct perf_event *event), const struct attribute_group *events, -- 2.25.1 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=-13.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 73D24C433E2 for ; Fri, 11 Sep 2020 21:53:06 +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 282AF22207 for ; Fri, 11 Sep 2020 21:53:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="GIJ30rqL" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 282AF22207 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org 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:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version: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=M0OfJcOoc2QzTeFZhukcFaW/uPHDTEOoviFuFpaxbYU=; b=GIJ30rqLzjlDBuqgO0e6XLeXu DCP1GDPLCsUKlTX/Rnk9yTRzXA4sQ6hBC/vxTIwYknlgu3xjbpfZcKczMDu2fQDhz4OmuXyiBcQjw Fgyh9egq2Sd8zKtG370fRjY4K8Tok0bCUhT9j0ttf5BuzwTWjB/4auwVzGLhSivSzDDc1cTUPd8ex 8ytXkdou59l4/jBXYnuKbro0s5PPIGepkVEjnmrAw3TOpcUhjoORIfwwVmgtfu265mUt13dzxKYXD 44BBSPTvcIxTkyIzW0OVtZhtDT5BVY9ybTkgJhBnAsSAxZtc1qsLPC7m4pDp9MUjCz2nEgBIK6uC/ wm9orIHCQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kGqx7-0003sm-Il; Fri, 11 Sep 2020 21:51:29 +0000 Received: from mail-io1-f68.google.com ([209.85.166.68]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kGqx2-0003pK-3X for linux-arm-kernel@lists.infradead.org; Fri, 11 Sep 2020 21:51:24 +0000 Received: by mail-io1-f68.google.com with SMTP id j2so12628160ioj.7 for ; Fri, 11 Sep 2020 14:51:22 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Z9z3VR6zD4FpK2wX25Sr8AogKHA4TBLm2zvFT7kdd5s=; b=ir8FkC92ySpXr7rb18L+ey16oS4ts5HyEI+QvwFH7UurIsnCAbhm3rkxzuXTtOF8Yl 0Nuz8ZMUe9AiHCZT6wf8TpKr6Ittfn2t7UzUZpbvXAuhipbUh2rA7ES8Y43W1FnoMoV2 pO/1Ue9tyfTMaJX1Z6078BaS/Pv/M5dkAuNluwqftFdlBVMA5m/8dd0bCGNi3RlsYqo3 /bNBg/jcd0EL9WEk+DWRBHtwUtafkxP5OHDTgyv1EW6rYwqpKejzOQAsWxSLxtGP43w2 3Kdw9d1Z6RGkPIxTYHJBMfeoaadVNvh/4IlA5XTXMMuvilHGozzTiSZeRUrXBljElgfe y3sw== X-Gm-Message-State: AOAM532yTXqVFTJaVBHT91ktNdxxx2sjjkv/k26vCNNKhSLylOVH3uzX 5E0bMquFvn0HvlJDRcpx6g== X-Google-Smtp-Source: ABdhPJxQx+roCAKx4AnaIPIlqaXgWUyZqSxBkBNIXV9ppawnV7/t50T8OV2VivzabOEHQrk8gp6dLw== X-Received: by 2002:a02:4b07:: with SMTP id q7mr4008190jaa.84.1599861081813; Fri, 11 Sep 2020 14:51:21 -0700 (PDT) Received: from xps15.herring.priv ([64.188.179.251]) by smtp.googlemail.com with ESMTPSA id a20sm1927966ilq.57.2020.09.11.14.51.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Sep 2020 14:51:21 -0700 (PDT) From: Rob Herring To: Will Deacon , Catalin Marinas , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Jiri Olsa Subject: [PATCH v3 01/10] arm64: pmu: Add hook to handle pmu-related undefined instructions Date: Fri, 11 Sep 2020 15:51:09 -0600 Message-Id: <20200911215118.2887710-2-robh@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200911215118.2887710-1-robh@kernel.org> References: <20200911215118.2887710-1-robh@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200911_175124_162163_021A0C4A X-CRM114-Status: GOOD ( 24.97 ) 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 , Ian Rogers , Alexander Shishkin , linux-kernel@vger.kernel.org, honnappa.nagarahalli@arm.com, Raphael Gault , Jonathan Cameron , Namhyung Kim , linux-arm-kernel@lists.infradead.org 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 From: Raphael Gault This patch introduces a protection for the userspace processes which are trying to access the registers from the pmu registers on a big.LITTLE environment. It introduces a hook to handle undefined instructions. The goal here is to prevent the process to be interrupted by a signal when the error is caused by the task being scheduled while accessing a counter, causing the counter access to be invalid. As we are not able to know efficiently the number of counters available physically on both pmu in that context we consider that any faulting access to a counter which is architecturally correct should not cause a SIGILL signal if the permissions are set accordingly. This commit also modifies the mask of the mrs_hook declared in arch/arm64/kernel/cpufeatures.c which emulates only feature register access. This is necessary because this hook's mask was too large and thus masking any mrs instruction, even if not related to the emulated registers which made the pmu emulation inefficient. Signed-off-by: Raphael Gault Signed-off-by: Rob Herring --- v2: - Fix warning for set but unused sys_reg --- arch/arm64/kernel/cpufeature.c | 4 +-- arch/arm64/kernel/perf_event.c | 54 ++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index a389b999482e..00bf53ffd9b0 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -2811,8 +2811,8 @@ static int emulate_mrs(struct pt_regs *regs, u32 insn) } static struct undef_hook mrs_hook = { - .instr_mask = 0xfff00000, - .instr_val = 0xd5300000, + .instr_mask = 0xffff0000, + .instr_val = 0xd5380000, .pstate_mask = PSR_AA32_MODE_MASK, .pstate_val = PSR_MODE_EL0t, .fn = emulate_mrs, diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 462f9a9cc44b..70538ae684da 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -8,9 +8,11 @@ * This code is based heavily on the ARMv7 perf event code. */ +#include #include #include #include +#include #include #include @@ -1016,6 +1018,58 @@ static int armv8pmu_probe_pmu(struct arm_pmu *cpu_pmu) return probe.present ? 0 : -ENODEV; } +static int emulate_pmu(struct pt_regs *regs, u32 insn) +{ + u32 rt; + u32 pmuserenr; + + rt = aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RT, insn); + pmuserenr = read_sysreg(pmuserenr_el0); + + if ((pmuserenr & (ARMV8_PMU_USERENR_ER|ARMV8_PMU_USERENR_CR)) != + (ARMV8_PMU_USERENR_ER|ARMV8_PMU_USERENR_CR)) + return -EINVAL; + + + /* + * Userspace is expected to only use this in the context of the scheme + * described in the struct perf_event_mmap_page comments. + * + * Given that context, we can only get here if we got migrated between + * getting the register index and doing the MSR read. This in turn + * implies we'll fail the sequence and retry, so any value returned is + * 'good', all we need is to be non-fatal. + * + * The choice of the value 0 is comming from the fact that when + * accessing a register which is not counting events but is accessible, + * we get 0. + */ + pt_regs_write_reg(regs, rt, 0); + + arm64_skip_faulting_instruction(regs, 4); + return 0; +} + +/* + * This hook will only be triggered by mrs + * instructions on PMU registers. This is mandatory + * in order to have a consistent behaviour even on + * big.LITTLE systems. + */ +static struct undef_hook pmu_hook = { + .instr_mask = 0xffff8800, + .instr_val = 0xd53b8800, + .fn = emulate_pmu, +}; + +static int __init enable_pmu_emulation(void) +{ + register_undef_hook(&pmu_hook); + return 0; +} + +core_initcall(enable_pmu_emulation); + static int armv8_pmu_init(struct arm_pmu *cpu_pmu, char *name, int (*map_event)(struct perf_event *event), const struct attribute_group *events, -- 2.25.1 _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel