All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marc Zyngier <marc.zyngier@arm.com>
To: Will Deacon <will.deacon@arm.com>
Cc: Itaru Kitayama <itaru.kitayama@riken.jp>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Hoan Tran <hotran@apm.com>,
	linux-arm-kernel@lists.infradead.org,
	kvmarm@lists.cs.columbia.edu, Tai Tri Nguyen <ttnguyen@apm.com>
Subject: Re: [PATCH 1/2] arm64: PMU: Do not use PMSELR_EL0 to access PMCCFILTR_EL0
Date: Tue, 6 Dec 2016 14:32:17 +0000	[thread overview]
Message-ID: <00b75c67-9d94-e9c3-6ae3-a706087bdd26@arm.com> (raw)
In-Reply-To: <20161206135020.GI2498@arm.com>

On 06/12/16 13:50, Will Deacon wrote:
> On Fri, Dec 02, 2016 at 03:50:58PM +0000, Marc Zyngier wrote:
>> The ARMv8 architecture allows the cycle counter to be configured
>> by setting PMSELR_EL0.SEL==0x1f and then accessing PMXEVTYPER_EL0,
>> hence accessing PMCCFILTR_EL0. But it disallows the use of
>> PMSELR_EL0.SEL==0x1f to access the cycle counter itself through
>> PMXEVCNTR_EL0.
>>
>> Linux itself doesn't violate this rule, but we may end up with
>> PMSELR_EL0.SEL being set to 0x1f when we enter a guest. If that
>> guest accesses PMXEVCNTR_EL0, the access may UNDEF at EL1,
>> despite the guest not having done anything wrong.
>>
>> In order to avoid this unfortunate course of events (haha!), let's
>> apply the same method armv8pmu_write_counter and co are using,
>> explicitely checking for the cycle counter and writing to
>> PMCCFILTR_EL0 directly. This prevents writing 0x1f to PMSELR_EL0,
>> and saves a Linux guest an extra trap.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm64/kernel/perf_event.c | 5 ++++-
>>  1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
>> index 57ae9d9..a65b757 100644
>> --- a/arch/arm64/kernel/perf_event.c
>> +++ b/arch/arm64/kernel/perf_event.c
>> @@ -632,7 +632,10 @@ static inline void armv8pmu_write_counter(struct perf_event *event, u32 value)
>>  
>>  static inline void armv8pmu_write_evtype(int idx, u32 val)
>>  {
>> -	if (armv8pmu_select_counter(idx) == idx) {
>> +	if (idx == ARMV8_IDX_CYCLE_COUNTER) {
>> +		val &= ARMV8_PMU_EVTYPE_MASK & ~ARMV8_PMU_EVTYPE_EVENT;
>> +		write_sysreg(val, pmccfiltr_el0);
>> +	} else if (armv8pmu_select_counter(idx) == idx) {
> 
> If we go down this route, then we also have to "fix" the 32-bit code,
> which uses PMSELR in a similar way. However, neither of the perf drivers
> are actually doing anything wrong here -- the problem comes about because
> the architecture doesn't guarantee that PMU accesses trap to EL2 unless
> both MDCR.TPM=1 *and* PMSELR_EL0 is valid. So I think that this should
> be handled together, in the KVM code that enables PMU traps.
> 
> Given that the perf callbacks tend to run with preemption disabled, I
> think you should be fine nuking PMSELR_EL0 to zero (i.e. no need to
> save/restore).

Fair enough. I'll respin another patch in a bit.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

WARNING: multiple messages have this Message-ID (diff)
From: marc.zyngier@arm.com (Marc Zyngier)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/2] arm64: PMU: Do not use PMSELR_EL0 to access PMCCFILTR_EL0
Date: Tue, 6 Dec 2016 14:32:17 +0000	[thread overview]
Message-ID: <00b75c67-9d94-e9c3-6ae3-a706087bdd26@arm.com> (raw)
In-Reply-To: <20161206135020.GI2498@arm.com>

On 06/12/16 13:50, Will Deacon wrote:
> On Fri, Dec 02, 2016 at 03:50:58PM +0000, Marc Zyngier wrote:
>> The ARMv8 architecture allows the cycle counter to be configured
>> by setting PMSELR_EL0.SEL==0x1f and then accessing PMXEVTYPER_EL0,
>> hence accessing PMCCFILTR_EL0. But it disallows the use of
>> PMSELR_EL0.SEL==0x1f to access the cycle counter itself through
>> PMXEVCNTR_EL0.
>>
>> Linux itself doesn't violate this rule, but we may end up with
>> PMSELR_EL0.SEL being set to 0x1f when we enter a guest. If that
>> guest accesses PMXEVCNTR_EL0, the access may UNDEF at EL1,
>> despite the guest not having done anything wrong.
>>
>> In order to avoid this unfortunate course of events (haha!), let's
>> apply the same method armv8pmu_write_counter and co are using,
>> explicitely checking for the cycle counter and writing to
>> PMCCFILTR_EL0 directly. This prevents writing 0x1f to PMSELR_EL0,
>> and saves a Linux guest an extra trap.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm64/kernel/perf_event.c | 5 ++++-
>>  1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
>> index 57ae9d9..a65b757 100644
>> --- a/arch/arm64/kernel/perf_event.c
>> +++ b/arch/arm64/kernel/perf_event.c
>> @@ -632,7 +632,10 @@ static inline void armv8pmu_write_counter(struct perf_event *event, u32 value)
>>  
>>  static inline void armv8pmu_write_evtype(int idx, u32 val)
>>  {
>> -	if (armv8pmu_select_counter(idx) == idx) {
>> +	if (idx == ARMV8_IDX_CYCLE_COUNTER) {
>> +		val &= ARMV8_PMU_EVTYPE_MASK & ~ARMV8_PMU_EVTYPE_EVENT;
>> +		write_sysreg(val, pmccfiltr_el0);
>> +	} else if (armv8pmu_select_counter(idx) == idx) {
> 
> If we go down this route, then we also have to "fix" the 32-bit code,
> which uses PMSELR in a similar way. However, neither of the perf drivers
> are actually doing anything wrong here -- the problem comes about because
> the architecture doesn't guarantee that PMU accesses trap to EL2 unless
> both MDCR.TPM=1 *and* PMSELR_EL0 is valid. So I think that this should
> be handled together, in the KVM code that enables PMU traps.
> 
> Given that the perf callbacks tend to run with preemption disabled, I
> think you should be fine nuking PMSELR_EL0 to zero (i.e. no need to
> save/restore).

Fair enough. I'll respin another patch in a bit.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

  reply	other threads:[~2016-12-06 14:31 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-02 15:50 [PATCH 0/2] arm64: PMU: Sanitize usage of PMSELR_EL0.SEL Marc Zyngier
2016-12-02 15:50 ` Marc Zyngier
2016-12-02 15:50 ` [PATCH 1/2] arm64: PMU: Do not use PMSELR_EL0 to access PMCCFILTR_EL0 Marc Zyngier
2016-12-02 15:50   ` Marc Zyngier
2016-12-06 13:50   ` Will Deacon
2016-12-06 13:50     ` Will Deacon
2016-12-06 14:32     ` Marc Zyngier [this message]
2016-12-06 14:32       ` Marc Zyngier
2016-12-02 15:50 ` [PATCH 2/2] arm64: PMU: Reset PMSELR_EL0 to a sane value at boot time Marc Zyngier
2016-12-02 15:50   ` Marc Zyngier
2016-12-02 21:28 ` [PATCH 0/2] arm64: PMU: Sanitize usage of PMSELR_EL0.SEL Itaru Kitayama
2016-12-02 21:28   ` Itaru Kitayama

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=00b75c67-9d94-e9c3-6ae3-a706087bdd26@arm.com \
    --to=marc.zyngier@arm.com \
    --cc=catalin.marinas@arm.com \
    --cc=hotran@apm.com \
    --cc=itaru.kitayama@riken.jp \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=ttnguyen@apm.com \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.