All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexandru Elisei <alexandru.elisei@arm.com>
To: Marc Zyngier <maz@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org, kvm@vger.kernel.org,
	kvmarm@lists.cs.columbia.edu, James Morse <james.morse@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Alexandre Chartre <alexandre.chartre@oracle.com>,
	Robin Murphy <robin.murphy@arm.com>,
	Andrew Jones <drjones@redhat.com>,
	Russell King <linux@arm.linux.org.uk>,
	kernel-team@android.com
Subject: Re: [PATCH v2 4/4] KVM: arm64: Remove PMSWINC_EL0 shadow register
Date: Tue, 20 Jul 2021 17:44:32 +0100	[thread overview]
Message-ID: <9ad0f6a5-fcd0-0179-efa7-7b35ed36e2ff@arm.com> (raw)
In-Reply-To: <f2b655d0977cde5483716f58ba2ab739@kernel.org>

Hi Marc,

On 7/19/21 5:56 PM, Marc Zyngier wrote:
> Hi Alex,
>
> On 2021-07-19 17:35, Alexandru Elisei wrote:
>> Hi Marc,
>>
>> On 7/19/21 1:39 PM, Marc Zyngier wrote:
>>> We keep an entry for the PMSWINC_EL0 register in the vcpu structure,
>>> while *never* writing anything there outside of reset.
>>>
>>> Given that the register is defined as write-only, that we always
>>> trap when this register is accessed, there is little point in saving
>>> anything anyway.
>>>
>>> Get rid of the entry, and save a mighty 8 bytes per vcpu structure.
>>>
>>> We still need to keep it exposed to userspace in order to preserve
>>> backward compatibility with previously saved VMs. Since userspace
>>> cannot expect any effect of writing to PMSWINC_EL0, treat the
>>> register as RAZ/WI for the purpose of userspace access.
>>>
>>> Signed-off-by: Marc Zyngier <maz@kernel.org>
>>> ---
>>>  arch/arm64/include/asm/kvm_host.h |  1 -
>>>  arch/arm64/kvm/sys_regs.c         | 21 ++++++++++++++++++++-
>>>  2 files changed, 20 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/arch/arm64/include/asm/kvm_host.h
>>> b/arch/arm64/include/asm/kvm_host.h
>>> index 41911585ae0c..afc169630884 100644
>>> --- a/arch/arm64/include/asm/kvm_host.h
>>> +++ b/arch/arm64/include/asm/kvm_host.h
>>> @@ -185,7 +185,6 @@ enum vcpu_sysreg {
>>>      PMCNTENSET_EL0,    /* Count Enable Set Register */
>>>      PMINTENSET_EL1,    /* Interrupt Enable Set Register */
>>>      PMOVSSET_EL0,    /* Overflow Flag Status Set Register */
>>> -    PMSWINC_EL0,    /* Software Increment Register */
>>>      PMUSERENR_EL0,    /* User Enable Register */
>>>
>>>      /* Pointer Authentication Registers in a strict increasing order. */
>>> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
>>> index f22139658e48..a1f5101f49a3 100644
>>> --- a/arch/arm64/kvm/sys_regs.c
>>> +++ b/arch/arm64/kvm/sys_regs.c
>>> @@ -1286,6 +1286,20 @@ static int set_raz_id_reg(struct kvm_vcpu *vcpu, const
>>> struct sys_reg_desc *rd,
>>>      return __set_id_reg(vcpu, rd, uaddr, true);
>>>  }
>>>
>>> +static int set_wi_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
>>> +              const struct kvm_one_reg *reg, void __user *uaddr)
>>> +{
>>> +    int err;
>>> +    u64 val;
>>> +
>>> +    /* Perform the access even if we are going to ignore the value */
>>> +    err = reg_from_user(&val, uaddr, sys_reg_to_index(rd));
>>
>> I don't understand why the read still happens if the value is ignored.
>> Just so KVM
>> preserves the previous behaviour and tells userspace there was an error?
>
> If userspace has given us a duff pointer, it needs to know about it.

Makes sense, thanks.

>
>>> +    if (err)
>>> +        return err;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>>  static bool access_ctr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
>>>                 const struct sys_reg_desc *r)
>>>  {
>>> @@ -1629,8 +1643,13 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>>>        .access = access_pmcnten, .reg = PMCNTENSET_EL0 },
>>>      { PMU_SYS_REG(SYS_PMOVSCLR_EL0),
>>>        .access = access_pmovs, .reg = PMOVSSET_EL0 },
>>> +    /*
>>> +     * PM_SWINC_EL0 is exposed to userspace as RAZ/WI, as it was
>>> +     * previously (and pointlessly) advertised in the past...
>>> +     */
>>>      { PMU_SYS_REG(SYS_PMSWINC_EL0),
>>> -      .access = access_pmswinc, .reg = PMSWINC_EL0 },
>>> +      .get_user = get_raz_id_reg, .set_user = set_wi_reg,
>>
>> In my opinion, the call chain to return 0 looks pretty confusing to me, as the
>> functions seemed made for ID register accesses, and the leaf function,
>> read_id_reg(), tries to match this register with a list of ID
>> registers. Since we
>> have already added a new function just for PMSWINC_EL0, I was
>> wondering if adding
>> another function, something like get_raz_reg(), would make more sense.
>
> In that case, I'd rather just kill get_raz_id_reg() and replace it with
> this get_raz_reg(). If we trat something as RAZ, who cares whether it is
> an idreg or not?

I agree, the Arm ARM doesn't make the distinction between ID registers and other
system registers in the definition of RAZ, I don't think KVM should either. And
the way read_id_reg() is written allows returning a value different than 0 even if
raz is true, which in my opinion could only happen because of a bug in KVM.

I can have a go at writing the patch(es) on top of this series, if you want. At
the moment I'm rewriting the KVM SPE series, so it will be a few weeks until I get
around to doing it though.

Thanks,

Alex


WARNING: multiple messages have this Message-ID (diff)
From: Alexandru Elisei <alexandru.elisei@arm.com>
To: Marc Zyngier <maz@kernel.org>
Cc: kvm@vger.kernel.org, kernel-team@android.com,
	Russell King <linux@arm.linux.org.uk>,
	Robin Murphy <robin.murphy@arm.com>,
	kvmarm@lists.cs.columbia.edu,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v2 4/4] KVM: arm64: Remove PMSWINC_EL0 shadow register
Date: Tue, 20 Jul 2021 17:44:32 +0100	[thread overview]
Message-ID: <9ad0f6a5-fcd0-0179-efa7-7b35ed36e2ff@arm.com> (raw)
In-Reply-To: <f2b655d0977cde5483716f58ba2ab739@kernel.org>

Hi Marc,

On 7/19/21 5:56 PM, Marc Zyngier wrote:
> Hi Alex,
>
> On 2021-07-19 17:35, Alexandru Elisei wrote:
>> Hi Marc,
>>
>> On 7/19/21 1:39 PM, Marc Zyngier wrote:
>>> We keep an entry for the PMSWINC_EL0 register in the vcpu structure,
>>> while *never* writing anything there outside of reset.
>>>
>>> Given that the register is defined as write-only, that we always
>>> trap when this register is accessed, there is little point in saving
>>> anything anyway.
>>>
>>> Get rid of the entry, and save a mighty 8 bytes per vcpu structure.
>>>
>>> We still need to keep it exposed to userspace in order to preserve
>>> backward compatibility with previously saved VMs. Since userspace
>>> cannot expect any effect of writing to PMSWINC_EL0, treat the
>>> register as RAZ/WI for the purpose of userspace access.
>>>
>>> Signed-off-by: Marc Zyngier <maz@kernel.org>
>>> ---
>>>  arch/arm64/include/asm/kvm_host.h |  1 -
>>>  arch/arm64/kvm/sys_regs.c         | 21 ++++++++++++++++++++-
>>>  2 files changed, 20 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/arch/arm64/include/asm/kvm_host.h
>>> b/arch/arm64/include/asm/kvm_host.h
>>> index 41911585ae0c..afc169630884 100644
>>> --- a/arch/arm64/include/asm/kvm_host.h
>>> +++ b/arch/arm64/include/asm/kvm_host.h
>>> @@ -185,7 +185,6 @@ enum vcpu_sysreg {
>>>      PMCNTENSET_EL0,    /* Count Enable Set Register */
>>>      PMINTENSET_EL1,    /* Interrupt Enable Set Register */
>>>      PMOVSSET_EL0,    /* Overflow Flag Status Set Register */
>>> -    PMSWINC_EL0,    /* Software Increment Register */
>>>      PMUSERENR_EL0,    /* User Enable Register */
>>>
>>>      /* Pointer Authentication Registers in a strict increasing order. */
>>> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
>>> index f22139658e48..a1f5101f49a3 100644
>>> --- a/arch/arm64/kvm/sys_regs.c
>>> +++ b/arch/arm64/kvm/sys_regs.c
>>> @@ -1286,6 +1286,20 @@ static int set_raz_id_reg(struct kvm_vcpu *vcpu, const
>>> struct sys_reg_desc *rd,
>>>      return __set_id_reg(vcpu, rd, uaddr, true);
>>>  }
>>>
>>> +static int set_wi_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
>>> +              const struct kvm_one_reg *reg, void __user *uaddr)
>>> +{
>>> +    int err;
>>> +    u64 val;
>>> +
>>> +    /* Perform the access even if we are going to ignore the value */
>>> +    err = reg_from_user(&val, uaddr, sys_reg_to_index(rd));
>>
>> I don't understand why the read still happens if the value is ignored.
>> Just so KVM
>> preserves the previous behaviour and tells userspace there was an error?
>
> If userspace has given us a duff pointer, it needs to know about it.

Makes sense, thanks.

>
>>> +    if (err)
>>> +        return err;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>>  static bool access_ctr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
>>>                 const struct sys_reg_desc *r)
>>>  {
>>> @@ -1629,8 +1643,13 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>>>        .access = access_pmcnten, .reg = PMCNTENSET_EL0 },
>>>      { PMU_SYS_REG(SYS_PMOVSCLR_EL0),
>>>        .access = access_pmovs, .reg = PMOVSSET_EL0 },
>>> +    /*
>>> +     * PM_SWINC_EL0 is exposed to userspace as RAZ/WI, as it was
>>> +     * previously (and pointlessly) advertised in the past...
>>> +     */
>>>      { PMU_SYS_REG(SYS_PMSWINC_EL0),
>>> -      .access = access_pmswinc, .reg = PMSWINC_EL0 },
>>> +      .get_user = get_raz_id_reg, .set_user = set_wi_reg,
>>
>> In my opinion, the call chain to return 0 looks pretty confusing to me, as the
>> functions seemed made for ID register accesses, and the leaf function,
>> read_id_reg(), tries to match this register with a list of ID
>> registers. Since we
>> have already added a new function just for PMSWINC_EL0, I was
>> wondering if adding
>> another function, something like get_raz_reg(), would make more sense.
>
> In that case, I'd rather just kill get_raz_id_reg() and replace it with
> this get_raz_reg(). If we trat something as RAZ, who cares whether it is
> an idreg or not?

I agree, the Arm ARM doesn't make the distinction between ID registers and other
system registers in the definition of RAZ, I don't think KVM should either. And
the way read_id_reg() is written allows returning a value different than 0 even if
raz is true, which in my opinion could only happen because of a bug in KVM.

I can have a go at writing the patch(es) on top of this series, if you want. At
the moment I'm rewriting the KVM SPE series, so it will be a few weeks until I get
around to doing it though.

Thanks,

Alex

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

WARNING: multiple messages have this Message-ID (diff)
From: Alexandru Elisei <alexandru.elisei@arm.com>
To: Marc Zyngier <maz@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org, kvm@vger.kernel.org,
	kvmarm@lists.cs.columbia.edu, James Morse <james.morse@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Alexandre Chartre <alexandre.chartre@oracle.com>,
	Robin Murphy <robin.murphy@arm.com>,
	Andrew Jones <drjones@redhat.com>,
	Russell King <linux@arm.linux.org.uk>,
	kernel-team@android.com
Subject: Re: [PATCH v2 4/4] KVM: arm64: Remove PMSWINC_EL0 shadow register
Date: Tue, 20 Jul 2021 17:44:32 +0100	[thread overview]
Message-ID: <9ad0f6a5-fcd0-0179-efa7-7b35ed36e2ff@arm.com> (raw)
In-Reply-To: <f2b655d0977cde5483716f58ba2ab739@kernel.org>

Hi Marc,

On 7/19/21 5:56 PM, Marc Zyngier wrote:
> Hi Alex,
>
> On 2021-07-19 17:35, Alexandru Elisei wrote:
>> Hi Marc,
>>
>> On 7/19/21 1:39 PM, Marc Zyngier wrote:
>>> We keep an entry for the PMSWINC_EL0 register in the vcpu structure,
>>> while *never* writing anything there outside of reset.
>>>
>>> Given that the register is defined as write-only, that we always
>>> trap when this register is accessed, there is little point in saving
>>> anything anyway.
>>>
>>> Get rid of the entry, and save a mighty 8 bytes per vcpu structure.
>>>
>>> We still need to keep it exposed to userspace in order to preserve
>>> backward compatibility with previously saved VMs. Since userspace
>>> cannot expect any effect of writing to PMSWINC_EL0, treat the
>>> register as RAZ/WI for the purpose of userspace access.
>>>
>>> Signed-off-by: Marc Zyngier <maz@kernel.org>
>>> ---
>>>  arch/arm64/include/asm/kvm_host.h |  1 -
>>>  arch/arm64/kvm/sys_regs.c         | 21 ++++++++++++++++++++-
>>>  2 files changed, 20 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/arch/arm64/include/asm/kvm_host.h
>>> b/arch/arm64/include/asm/kvm_host.h
>>> index 41911585ae0c..afc169630884 100644
>>> --- a/arch/arm64/include/asm/kvm_host.h
>>> +++ b/arch/arm64/include/asm/kvm_host.h
>>> @@ -185,7 +185,6 @@ enum vcpu_sysreg {
>>>      PMCNTENSET_EL0,    /* Count Enable Set Register */
>>>      PMINTENSET_EL1,    /* Interrupt Enable Set Register */
>>>      PMOVSSET_EL0,    /* Overflow Flag Status Set Register */
>>> -    PMSWINC_EL0,    /* Software Increment Register */
>>>      PMUSERENR_EL0,    /* User Enable Register */
>>>
>>>      /* Pointer Authentication Registers in a strict increasing order. */
>>> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
>>> index f22139658e48..a1f5101f49a3 100644
>>> --- a/arch/arm64/kvm/sys_regs.c
>>> +++ b/arch/arm64/kvm/sys_regs.c
>>> @@ -1286,6 +1286,20 @@ static int set_raz_id_reg(struct kvm_vcpu *vcpu, const
>>> struct sys_reg_desc *rd,
>>>      return __set_id_reg(vcpu, rd, uaddr, true);
>>>  }
>>>
>>> +static int set_wi_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
>>> +              const struct kvm_one_reg *reg, void __user *uaddr)
>>> +{
>>> +    int err;
>>> +    u64 val;
>>> +
>>> +    /* Perform the access even if we are going to ignore the value */
>>> +    err = reg_from_user(&val, uaddr, sys_reg_to_index(rd));
>>
>> I don't understand why the read still happens if the value is ignored.
>> Just so KVM
>> preserves the previous behaviour and tells userspace there was an error?
>
> If userspace has given us a duff pointer, it needs to know about it.

Makes sense, thanks.

>
>>> +    if (err)
>>> +        return err;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>>  static bool access_ctr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
>>>                 const struct sys_reg_desc *r)
>>>  {
>>> @@ -1629,8 +1643,13 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>>>        .access = access_pmcnten, .reg = PMCNTENSET_EL0 },
>>>      { PMU_SYS_REG(SYS_PMOVSCLR_EL0),
>>>        .access = access_pmovs, .reg = PMOVSSET_EL0 },
>>> +    /*
>>> +     * PM_SWINC_EL0 is exposed to userspace as RAZ/WI, as it was
>>> +     * previously (and pointlessly) advertised in the past...
>>> +     */
>>>      { PMU_SYS_REG(SYS_PMSWINC_EL0),
>>> -      .access = access_pmswinc, .reg = PMSWINC_EL0 },
>>> +      .get_user = get_raz_id_reg, .set_user = set_wi_reg,
>>
>> In my opinion, the call chain to return 0 looks pretty confusing to me, as the
>> functions seemed made for ID register accesses, and the leaf function,
>> read_id_reg(), tries to match this register with a list of ID
>> registers. Since we
>> have already added a new function just for PMSWINC_EL0, I was
>> wondering if adding
>> another function, something like get_raz_reg(), would make more sense.
>
> In that case, I'd rather just kill get_raz_id_reg() and replace it with
> this get_raz_reg(). If we trat something as RAZ, who cares whether it is
> an idreg or not?

I agree, the Arm ARM doesn't make the distinction between ID registers and other
system registers in the definition of RAZ, I don't think KVM should either. And
the way read_id_reg() is written allows returning a value different than 0 even if
raz is true, which in my opinion could only happen because of a bug in KVM.

I can have a go at writing the patch(es) on top of this series, if you want. At
the moment I'm rewriting the KVM SPE series, so it will be a few weeks until I get
around to doing it though.

Thanks,

Alex


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2021-07-20 16:45 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-19 12:38 [PATCH v2 0/4] kvm-arm64: Fix PMU reset values (and more) Marc Zyngier
2021-07-19 12:38 ` Marc Zyngier
2021-07-19 12:38 ` Marc Zyngier
2021-07-19 12:38 ` [PATCH v2 1/4] KVM: arm64: Narrow PMU sysreg reset values to architectural requirements Marc Zyngier
2021-07-19 12:38   ` Marc Zyngier
2021-07-19 12:38   ` Marc Zyngier
2021-07-19 15:55   ` Alexandru Elisei
2021-07-19 15:55     ` Alexandru Elisei
2021-07-19 15:55     ` Alexandru Elisei
2021-07-19 15:56     ` Marc Zyngier
2021-07-19 15:56       ` Marc Zyngier
2021-07-19 15:56       ` Marc Zyngier
2021-07-19 16:02       ` Alexandru Elisei
2021-07-19 16:02         ` Alexandru Elisei
2021-07-19 16:02         ` Alexandru Elisei
2021-07-19 12:39 ` [PATCH v2 2/4] KVM: arm64: Drop unnecessary masking of PMU registers Marc Zyngier
2021-07-19 12:39   ` Marc Zyngier
2021-07-19 12:39   ` Marc Zyngier
2021-07-19 12:39 ` [PATCH v2 3/4] KVM: arm64: Disabling disabled PMU counters wastes a lot of time Marc Zyngier
2021-07-19 12:39   ` Marc Zyngier
2021-07-19 12:39   ` Marc Zyngier
2021-07-19 12:39 ` [PATCH v2 4/4] KVM: arm64: Remove PMSWINC_EL0 shadow register Marc Zyngier
2021-07-19 12:39   ` Marc Zyngier
2021-07-19 12:39   ` Marc Zyngier
2021-07-19 16:35   ` Alexandru Elisei
2021-07-19 16:35     ` Alexandru Elisei
2021-07-19 16:35     ` Alexandru Elisei
2021-07-19 16:56     ` Marc Zyngier
2021-07-19 16:56       ` Marc Zyngier
2021-07-19 16:56       ` Marc Zyngier
2021-07-20 16:44       ` Alexandru Elisei [this message]
2021-07-20 16:44         ` Alexandru Elisei
2021-07-20 16:44         ` Alexandru Elisei
2021-07-21  9:30         ` Marc Zyngier
2021-07-21  9:30           ` Marc Zyngier
2021-07-21  9:30           ` Marc Zyngier
2021-08-02 13:39 ` [PATCH v2 0/4] kvm-arm64: Fix PMU reset values (and more) Marc Zyngier
2021-08-02 13:39   ` Marc Zyngier
2021-08-02 13:39   ` Marc Zyngier

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=9ad0f6a5-fcd0-0179-efa7-7b35ed36e2ff@arm.com \
    --to=alexandru.elisei@arm.com \
    --cc=alexandre.chartre@oracle.com \
    --cc=drjones@redhat.com \
    --cc=james.morse@arm.com \
    --cc=kernel-team@android.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux@arm.linux.org.uk \
    --cc=maz@kernel.org \
    --cc=robin.murphy@arm.com \
    --cc=suzuki.poulose@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.