diff mbox series

[3/5] kvm: arm64: Limit PMU version to ARMv8.1

Message ID 20200216185324.32596-4-maz@kernel.org (mailing list archive)
State New, archived
Headers show
Series Random debug/PMU fixes for 5.6 | expand

Commit Message

Marc Zyngier Feb. 16, 2020, 6:53 p.m. UTC
Our PMU code is only implementing the ARMv8.1 features, so let's
stick to this when reporting the feature set to the guest.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 5 +++++
 1 file changed, 5 insertions(+)

Comments

James Morse Feb. 18, 2020, 5:43 p.m. UTC | #1
Hi Marc,

On 16/02/2020 18:53, Marc Zyngier wrote:
> Our PMU code is only implementing the ARMv8.1 features, so let's
> stick to this when reporting the feature set to the guest.

> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 682fedd7700f..06b2d0dc6c73 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -1093,6 +1093,11 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
>  				 FEATURE(ID_AA64ISAR1_GPA) |
>  				 FEATURE(ID_AA64ISAR1_GPI));
>  		break;
> +	case SYS_ID_AA64DFR0_EL1:
> +		/* Limit PMU to ARMv8.1 */

Not just limit, but upgrade too! (force?)
This looks safe because ARMV8_PMU_EVTYPE_EVENT always includes the extra bits this added,
and the register is always trapped.


The PMU version is also readable via ID_DFR0_EL1.PerfMon, should that be sanitised to be
the same?
(I don't think we've hidden an aarch64 feature that also existed in aarch32 before).


Regardless:
Reviewed-by: James Morse <james.morse@arm.com>


Thanks,

James



> +		val &= ~FEATURE(ID_AA64DFR0_PMUVER);
> +		val |= FIELD_PREP(FEATURE(ID_AA64DFR0_PMUVER), 4);
> +		break;
>  	}
>  
>  	return val;
>
Marc Zyngier Feb. 19, 2020, 9:46 a.m. UTC | #2
On 2020-02-18 17:43, James Morse wrote:
> Hi Marc,
> 
> On 16/02/2020 18:53, Marc Zyngier wrote:
>> Our PMU code is only implementing the ARMv8.1 features, so let's
>> stick to this when reporting the feature set to the guest.
> 
>> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
>> index 682fedd7700f..06b2d0dc6c73 100644
>> --- a/arch/arm64/kvm/sys_regs.c
>> +++ b/arch/arm64/kvm/sys_regs.c
>> @@ -1093,6 +1093,11 @@ static u64 read_id_reg(const struct kvm_vcpu 
>> *vcpu,
>>  				 FEATURE(ID_AA64ISAR1_GPA) |
>>  				 FEATURE(ID_AA64ISAR1_GPI));
>>  		break;
>> +	case SYS_ID_AA64DFR0_EL1:
>> +		/* Limit PMU to ARMv8.1 */
> 
> Not just limit, but upgrade too! (force?)
> This looks safe because ARMV8_PMU_EVTYPE_EVENT always includes the
> extra bits this added, and the register is always trapped.

That's definitely not what I intended! Let me fix that one.

> The PMU version is also readable via ID_DFR0_EL1.PerfMon, should that
> be sanitised to be the same? (I don't think we've hidden an aarch64
> feature that also existed in aarch32 before).

Indeed, yet another oversight. I'll fix that too.

> Regardless:
> Reviewed-by: James Morse <james.morse@arm.com>

You're way too kind! ;-)

         M.
James Morse Feb. 19, 2020, 10:18 a.m. UTC | #3
Hi Marc,

On 2/19/20 9:46 AM, Marc Zyngier wrote:
> On 2020-02-18 17:43, James Morse wrote:
>> Hi Marc,
>>
>> On 16/02/2020 18:53, Marc Zyngier wrote:
>>> Our PMU code is only implementing the ARMv8.1 features, so let's
>>> stick to this when reporting the feature set to the guest.
>>
>>> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
>>> index 682fedd7700f..06b2d0dc6c73 100644
>>> --- a/arch/arm64/kvm/sys_regs.c
>>> +++ b/arch/arm64/kvm/sys_regs.c
>>> @@ -1093,6 +1093,11 @@ static u64 read_id_reg(const struct kvm_vcpu
>>> *vcpu,
>>>                   FEATURE(ID_AA64ISAR1_GPA) |
>>>                   FEATURE(ID_AA64ISAR1_GPI));
>>>          break;
>>> +    case SYS_ID_AA64DFR0_EL1:
>>> +        /* Limit PMU to ARMv8.1 */
>>
>> Not just limit, but upgrade too! (force?)
>> This looks safe because ARMV8_PMU_EVTYPE_EVENT always includes the
>> extra bits this added, and the register is always trapped.
> 
> That's definitely not what I intended! Let me fix that one.

What goes wrong?

The register description says to support v8.1 you need:
| Extended 16-bit PMEVTYPER<n>_EL0.evtCount field
| If EL2 is implemented, the MDCR_EL2.HPMD control bit

It looks like the extended PMEVTYPER would work via the emulation, and
EL2 guests are totally crazy.

Is the STALL_* bits in ARMv8.1-PMU the problem, ... or the extra work
for NV?


>> The PMU version is also readable via ID_DFR0_EL1.PerfMon, should that
>> be sanitised to be the same? (I don't think we've hidden an aarch64
>> feature that also existed in aarch32 before).
> 
> Indeed, yet another oversight. I'll fix that too.

(Weird variation in the aarch32 and aarch64 ID registers isn't something
I care about ... who would ever look at both?)



Thanks,

James
Marc Zyngier Feb. 19, 2020, 11:14 a.m. UTC | #4
On 2020-02-19 10:18, James Morse wrote:
> Hi Marc,
> 
> On 2/19/20 9:46 AM, Marc Zyngier wrote:
>> On 2020-02-18 17:43, James Morse wrote:
>>> Hi Marc,
>>> 
>>> On 16/02/2020 18:53, Marc Zyngier wrote:
>>>> Our PMU code is only implementing the ARMv8.1 features, so let's
>>>> stick to this when reporting the feature set to the guest.
>>> 
>>>> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
>>>> index 682fedd7700f..06b2d0dc6c73 100644
>>>> --- a/arch/arm64/kvm/sys_regs.c
>>>> +++ b/arch/arm64/kvm/sys_regs.c
>>>> @@ -1093,6 +1093,11 @@ static u64 read_id_reg(const struct kvm_vcpu
>>>> *vcpu,
>>>>                   FEATURE(ID_AA64ISAR1_GPA) |
>>>>                   FEATURE(ID_AA64ISAR1_GPI));
>>>>          break;
>>>> +    case SYS_ID_AA64DFR0_EL1:
>>>> +        /* Limit PMU to ARMv8.1 */
>>> 
>>> Not just limit, but upgrade too! (force?)
>>> This looks safe because ARMV8_PMU_EVTYPE_EVENT always includes the
>>> extra bits this added, and the register is always trapped.
>> 
>> That's definitely not what I intended! Let me fix that one.
> 
> What goes wrong?
> 
> The register description says to support v8.1 you need:
> | Extended 16-bit PMEVTYPER<n>_EL0.evtCount field
> | If EL2 is implemented, the MDCR_EL2.HPMD control bit
> 
> It looks like the extended PMEVTYPER would work via the emulation, and
> EL2 guests are totally crazy.
> 
> Is the STALL_* bits in ARMv8.1-PMU the problem, ... or the extra work
> for NV?

What goes wrong is that on a v8.0 system, the guest could be tempted to
use events in the 0x0400-0xffff range. It wouldn't break anything, but
it wouldn't give the expected result.

I don't care much for PMU support in EL2 guests at this stage.

>>> The PMU version is also readable via ID_DFR0_EL1.PerfMon, should that
>>> be sanitised to be the same? (I don't think we've hidden an aarch64
>>> feature that also existed in aarch32 before).
>> 
>> Indeed, yet another oversight. I'll fix that too.
> 
> (Weird variation in the aarch32 and aarch64 ID registers isn't 
> something
> I care about ... who would ever look at both?)

A 64bit guest running a 32bit EL0?

         M.
diff mbox series

Patch

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 682fedd7700f..06b2d0dc6c73 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1093,6 +1093,11 @@  static u64 read_id_reg(const struct kvm_vcpu *vcpu,
 				 FEATURE(ID_AA64ISAR1_GPA) |
 				 FEATURE(ID_AA64ISAR1_GPI));
 		break;
+	case SYS_ID_AA64DFR0_EL1:
+		/* Limit PMU to ARMv8.1 */
+		val &= ~FEATURE(ID_AA64DFR0_PMUVER);
+		val |= FIELD_PREP(FEATURE(ID_AA64DFR0_PMUVER), 4);
+		break;
 	}
 
 	return val;