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=-10.1 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,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 DBD99C433E1 for ; Tue, 7 Jul 2020 20:53:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B9F49206F6 for ; Tue, 7 Jul 2020 20:53:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1594155223; bh=zkFjkplM0GDkYO9QlX2A0qg7HKN/F+qnN/YManly1L4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=Y7E95hqhD+etxsAzUVzESpO5kIGpb8bswG512gqn5+ncwTXOsgMYraNdI7nVi+IwQ wWTrKQy1EFidT+0le7sASkPEtsHk+xcR381JA0Yq2hltudOsGh4IUvyi6+UN6l/zkc WRtGzLzHhIUPEIGhyxNwcnVFnaWbtOdt07kk3CTY= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729060AbgGGUxm (ORCPT ); Tue, 7 Jul 2020 16:53:42 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:44022 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729013AbgGGUxj (ORCPT ); Tue, 7 Jul 2020 16:53:39 -0400 Received: by mail-io1-f65.google.com with SMTP id k23so44625405iom.10 for ; Tue, 07 Jul 2020 13:53:38 -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=MutG5e0ak9+mnQszlEcX011m8VM8IwdPrWKEFzeJcKg=; b=VaPf1+aFKZfWasmTGBBYJjI8DFYqvl34d1yth1NCAMiD5H2vvj9mExkaXrbSN16PEA 1PmEfFxQ2lgV0ni0YLqVzR9j+T2WCCgntxxBA0z/6ckSP+FAlwC798CZ1Srkm+ywNNHg rTGZiSq1pKbN2Vi0fzqZhjL5utN8yR+C4rwhYftACrkfYNj86fkjoqS/9mBL30QDpSIm XlVeYVlYksFcFcfmzKa6e+fVEH5IVb922MvYX70UVWgn00qFETg/wblmDVRq0sqBJmo4 QTPnYHBRE1FZd5M4nmvCt9GvGI7zZEktCI1okmJouoqYctc8S45vBxbyJkkhNXUlZlgg 7+fw== X-Gm-Message-State: AOAM532Oy11DbQp4Etbpv5Lkp2kBbueHPp+tcaXeQjautMJ1cO31i7cn k1jBwlH9CCGDcdeeU4h2eg== X-Google-Smtp-Source: ABdhPJwfNIlmhSEBsPu6mZcdiF3gwDsJlyvfkbi1HICFy/WuYQawQxuYTX43Lww3xbuf+BVN2+w8Aw== X-Received: by 2002:a02:cd06:: with SMTP id g6mr30640822jaq.37.1594155218139; Tue, 07 Jul 2020 13:53:38 -0700 (PDT) Received: from xps15.herring.priv ([64.188.179.254]) by smtp.googlemail.com with ESMTPSA id y6sm13110712ila.74.2020.07.07.13.53.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Jul 2020 13:53:37 -0700 (PDT) From: Rob Herring To: Will Deacon , Catalin Marinas Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Raphael Gault , Jonathan Cameron Subject: [PATCH 2/5] arm64: pmu: Add hook to handle pmu-related undefined instructions Date: Tue, 7 Jul 2020 14:53:30 -0600 Message-Id: <20200707205333.624938-3-robh@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200707205333.624938-1-robh@kernel.org> References: <20200707205333.624938-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 --- arch/arm64/kernel/cpufeature.c | 4 +-- arch/arm64/kernel/perf_event.c | 55 ++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 4ae41670c2e6..2a34adac86c6 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -2744,8 +2744,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 4d7879484cec..d4b4fe69fe2c 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 @@ -991,6 +993,59 @@ 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 sys_reg, rt; + u32 pmuserenr; + + sys_reg = (u32)aarch64_insn_decode_immediate(AARCH64_INSN_IMM_16, insn) << 5; + 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=-10.0 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE, SPF_PASS,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 1F2C7C433DF for ; Tue, 7 Jul 2020 20:55:26 +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 DD771206CD for ; Tue, 7 Jul 2020 20:55:25 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Me7ptRLt" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DD771206CD 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=Wjv+Z9OVcqq1cboAhoJCvQBC+lgIGHCETVMEqN5luEY=; b=Me7ptRLt+ut0p/u/ZourRqv9b a2mBhFjSsXpr5HhpzEIF7MM0MaAY1KTUlrk2rwbBQxVGVDcVDFg3GjUeUmnt5UbfPql58y4Y2JLZL tMA1mrfyr3+/Jj0bj/sBUYeXHG8y2zIeCwThZYnxtg4nnhK1pjVwDJ+sEQ3QEFkaIj9BaJSTAZ1td B9ydp0A1JaBIrNniM0kFZR8mVnBUDRfyPIXbeTeJQ0t/8xRGL7UiyrTM6+9BCyWATJRn4/rDI7j58 762ZM6jHHsUSj33lIAC+Qc2xW+zDxENv6hHNy6O0ih5e9ueDdbk7gijyk7XYjk/QRQ7LnUBnZti1o YZmJx5BZA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jsubM-0003vv-DO; Tue, 07 Jul 2020 20:54:04 +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 1jsub0-0003nG-0X for linux-arm-kernel@lists.infradead.org; Tue, 07 Jul 2020 20:53:46 +0000 Received: by mail-io1-f68.google.com with SMTP id v6so31029474iob.4 for ; Tue, 07 Jul 2020 13:53:38 -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=MutG5e0ak9+mnQszlEcX011m8VM8IwdPrWKEFzeJcKg=; b=p0TLbGUsD3lal9OeI/Fi1cSVZ7ndggy5ESDMLXbF/mL+eNuvGBEeWKQ/Eqi634QvHv 5vtlBh3AsvNLAMtsWVo5DTlT+gDix2LvnuDUAjmyhuHUFoAMBohp/HKiUb9mO2pzXRjA 7egPrFnhER126zufl+CJHMckMPqGgBZR3t+W+t0D1OLiJs+8n3OMLSPYTm2FEURFDZLv trfGGjKUDhJ1mnKSuO1MiE9AjAOKRJwarRE8sp9QWODGOaKEkA6UIveZZTfXVaYSokNV BnZBB92DYtVA9h3yvQ66yx0F7VR6YQ8+s2h9U1B/rtRvhWXxRrT2PitBtXRj+WZ5DWha d4yg== X-Gm-Message-State: AOAM533IWxPVrf/nOneIQeTLCdERZBbz3/AUIwYh6Z1Y0hMOolPPJ94f 2GlRqG614P/Oi9oDoVr3ew== X-Google-Smtp-Source: ABdhPJwfNIlmhSEBsPu6mZcdiF3gwDsJlyvfkbi1HICFy/WuYQawQxuYTX43Lww3xbuf+BVN2+w8Aw== X-Received: by 2002:a02:cd06:: with SMTP id g6mr30640822jaq.37.1594155218139; Tue, 07 Jul 2020 13:53:38 -0700 (PDT) Received: from xps15.herring.priv ([64.188.179.254]) by smtp.googlemail.com with ESMTPSA id y6sm13110712ila.74.2020.07.07.13.53.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Jul 2020 13:53:37 -0700 (PDT) From: Rob Herring To: Will Deacon , Catalin Marinas Subject: [PATCH 2/5] arm64: pmu: Add hook to handle pmu-related undefined instructions Date: Tue, 7 Jul 2020 14:53:30 -0600 Message-Id: <20200707205333.624938-3-robh@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200707205333.624938-1-robh@kernel.org> References: <20200707205333.624938-1-robh@kernel.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200707_165342_278759_30FFE1C9 X-CRM114-Status: GOOD ( 22.98 ) 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 , Peter Zijlstra , linux-kernel@vger.kernel.org, Arnaldo Carvalho de Melo , Alexander Shishkin , Raphael Gault , Ingo Molnar , Jonathan Cameron , Namhyung Kim , Jiri Olsa , 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 --- arch/arm64/kernel/cpufeature.c | 4 +-- arch/arm64/kernel/perf_event.c | 55 ++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 4ae41670c2e6..2a34adac86c6 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -2744,8 +2744,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 4d7879484cec..d4b4fe69fe2c 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 @@ -991,6 +993,59 @@ 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 sys_reg, rt; + u32 pmuserenr; + + sys_reg = (u32)aarch64_insn_decode_immediate(AARCH64_INSN_IMM_16, insn) << 5; + 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