All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marc Zyngier <maz@kernel.org>
To: Raghavendra Rao Ananta <rananta@google.com>
Cc: Oliver Upton <oliver.upton@linux.dev>,
	Alexandru Elisei <alexandru.elisei@arm.com>,
	James Morse <james.morse@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Zenghui Yu <yuzenghui@huawei.com>,
	Shaoqin Huang <shahuang@redhat.com>,
	Jing Zhang <jingzhangos@google.com>,
	Reiji Watanabe <reijiw@google.com>,
	Colton Lewis <coltonlewis@google.com>,
	linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
	linux-kernel@vger.kernel.org, kvm@vger.kernel.org
Subject: Re: [PATCH v8 07/13] KVM: arm64: PMU: Allow userspace to limit PMCR_EL0.N for the guest
Date: Mon, 23 Oct 2023 14:00:18 +0100	[thread overview]
Message-ID: <86wmvd4hp9.wl-maz@kernel.org> (raw)
In-Reply-To: <20231020214053.2144305-8-rananta@google.com>

On Fri, 20 Oct 2023 22:40:47 +0100,
Raghavendra Rao Ananta <rananta@google.com> wrote:
> 
> From: Reiji Watanabe <reijiw@google.com>
> 
> KVM does not yet support userspace modifying PMCR_EL0.N (With
> the previous patch, KVM ignores what is written by userspace).
> Add support userspace limiting PMCR_EL0.N.
> 
> Disallow userspace to set PMCR_EL0.N to a value that is greater
> than the host value as KVM doesn't support more event counters
> than what the host HW implements. Also, make this register
> immutable after the VM has started running. To maintain the
> existing expectations, instead of returning an error, KVM
> returns a success for these two cases.
> 
> Finally, ignore writes to read-only bits that are cleared on
> vCPU reset, and RES{0,1} bits (including writable bits that
> KVM doesn't support yet), as those bits shouldn't be modified
> (at least with the current KVM).
> 
> Signed-off-by: Reiji Watanabe <reijiw@google.com>
> Signed-off-by: Raghavendra Rao Ananta <rananta@google.com>
> ---
>  arch/arm64/kvm/sys_regs.c | 57 +++++++++++++++++++++++++++++++++++++--
>  1 file changed, 55 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 2e5d497596ef8..a2c5f210b3d6b 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -1176,6 +1176,59 @@ static int get_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
>  	return 0;
>  }
>  
> +static int set_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
> +		    u64 val)
> +{
> +	struct kvm *kvm = vcpu->kvm;
> +	u64 new_n, mutable_mask;

Really, this lacks consistency. Either you make N a u8 everywhere, or
a u64 everywhere. I don't mind either, but the type confusion is not
great.

> +
> +	mutex_lock(&kvm->arch.config_lock);
> +
> +	/*
> +	 * Make PMCR immutable once the VM has started running, but
> +	 * do not return an error to meet the existing expectations.
> +	 */
> +	if (kvm_vm_has_ran_once(vcpu->kvm)) {
> +		mutex_unlock(&kvm->arch.config_lock);
> +		return 0;
> +	}
> +
> +	new_n = (val >> ARMV8_PMU_PMCR_N_SHIFT) & ARMV8_PMU_PMCR_N_MASK;
> +	if (new_n != kvm->arch.pmcr_n) {

Why do we need to check this?

> +		u8 pmcr_n_limit = kvm_arm_pmu_get_max_counters(kvm);

Can you see why I'm annoyed?

> +
> +		/*
> +		 * The vCPU can't have more counters than the PMU hardware
> +		 * implements. Ignore this error to maintain compatibility
> +		 * with the existing KVM behavior.
> +		 */
> +		if (new_n <= pmcr_n_limit)

Isn't this the only thing that actually matters?

> +			kvm->arch.pmcr_n = new_n;
> +	}
> +	mutex_unlock(&kvm->arch.config_lock);
> +
> +	/*
> +	 * Ignore writes to RES0 bits, read only bits that are cleared on
> +	 * vCPU reset, and writable bits that KVM doesn't support yet.
> +	 * (i.e. only PMCR.N and bits [7:0] are mutable from userspace)
> +	 * The LP bit is RES0 when FEAT_PMUv3p5 is not supported on the vCPU.
> +	 * But, we leave the bit as it is here, as the vCPU's PMUver might
> +	 * be changed later (NOTE: the bit will be cleared on first vCPU run
> +	 * if necessary).
> +	 */
> +	mutable_mask = (ARMV8_PMU_PMCR_MASK |
> +			(ARMV8_PMU_PMCR_N_MASK << ARMV8_PMU_PMCR_N_SHIFT));

Why is N part of the 'mutable' mask? The only bits that should make it
into the register are ARMV8_PMU_PMCR_MASK.

> +	val &= mutable_mask;
> +	val |= (__vcpu_sys_reg(vcpu, r->reg) & ~mutable_mask);
> +
> +	/* The LC bit is RES1 when AArch32 is not supported */
> +	if (!kvm_supports_32bit_el0())
> +		val |= ARMV8_PMU_PMCR_LC;
> +
> +	__vcpu_sys_reg(vcpu, r->reg) = val;
> +	return 0;

I think this should be rewritten as:

	val &= ARMV8_PMU_PMCR_MASK;
	/* The LC bit is RES1 when AArch32 is not supported */
	if (!kvm_supports_32bit_el0())
		val |= ARMV8_PMU_PMCR_LC;

	__vcpu_sys_reg(vcpu, r->reg) = val;
	return 0;

And that's it. Drop this 'mutable_mask' nonsense, as we should be
getting the correct value (merge of the per-vcpu register and VM-wide
N) since patch 4.

	M.

-- 
Without deviation from the norm, progress is not possible.

WARNING: multiple messages have this Message-ID (diff)
From: Marc Zyngier <maz@kernel.org>
To: Raghavendra Rao Ananta <rananta@google.com>
Cc: Oliver Upton <oliver.upton@linux.dev>,
	Alexandru Elisei <alexandru.elisei@arm.com>,
	James Morse <james.morse@arm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Zenghui Yu <yuzenghui@huawei.com>,
	Shaoqin Huang <shahuang@redhat.com>,
	Jing Zhang <jingzhangos@google.com>,
	Reiji Watanabe <reijiw@google.com>,
	Colton Lewis <coltonlewis@google.com>,
	linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
	linux-kernel@vger.kernel.org, kvm@vger.kernel.org
Subject: Re: [PATCH v8 07/13] KVM: arm64: PMU: Allow userspace to limit PMCR_EL0.N for the guest
Date: Mon, 23 Oct 2023 14:00:18 +0100	[thread overview]
Message-ID: <86wmvd4hp9.wl-maz@kernel.org> (raw)
In-Reply-To: <20231020214053.2144305-8-rananta@google.com>

On Fri, 20 Oct 2023 22:40:47 +0100,
Raghavendra Rao Ananta <rananta@google.com> wrote:
> 
> From: Reiji Watanabe <reijiw@google.com>
> 
> KVM does not yet support userspace modifying PMCR_EL0.N (With
> the previous patch, KVM ignores what is written by userspace).
> Add support userspace limiting PMCR_EL0.N.
> 
> Disallow userspace to set PMCR_EL0.N to a value that is greater
> than the host value as KVM doesn't support more event counters
> than what the host HW implements. Also, make this register
> immutable after the VM has started running. To maintain the
> existing expectations, instead of returning an error, KVM
> returns a success for these two cases.
> 
> Finally, ignore writes to read-only bits that are cleared on
> vCPU reset, and RES{0,1} bits (including writable bits that
> KVM doesn't support yet), as those bits shouldn't be modified
> (at least with the current KVM).
> 
> Signed-off-by: Reiji Watanabe <reijiw@google.com>
> Signed-off-by: Raghavendra Rao Ananta <rananta@google.com>
> ---
>  arch/arm64/kvm/sys_regs.c | 57 +++++++++++++++++++++++++++++++++++++--
>  1 file changed, 55 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 2e5d497596ef8..a2c5f210b3d6b 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -1176,6 +1176,59 @@ static int get_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
>  	return 0;
>  }
>  
> +static int set_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
> +		    u64 val)
> +{
> +	struct kvm *kvm = vcpu->kvm;
> +	u64 new_n, mutable_mask;

Really, this lacks consistency. Either you make N a u8 everywhere, or
a u64 everywhere. I don't mind either, but the type confusion is not
great.

> +
> +	mutex_lock(&kvm->arch.config_lock);
> +
> +	/*
> +	 * Make PMCR immutable once the VM has started running, but
> +	 * do not return an error to meet the existing expectations.
> +	 */
> +	if (kvm_vm_has_ran_once(vcpu->kvm)) {
> +		mutex_unlock(&kvm->arch.config_lock);
> +		return 0;
> +	}
> +
> +	new_n = (val >> ARMV8_PMU_PMCR_N_SHIFT) & ARMV8_PMU_PMCR_N_MASK;
> +	if (new_n != kvm->arch.pmcr_n) {

Why do we need to check this?

> +		u8 pmcr_n_limit = kvm_arm_pmu_get_max_counters(kvm);

Can you see why I'm annoyed?

> +
> +		/*
> +		 * The vCPU can't have more counters than the PMU hardware
> +		 * implements. Ignore this error to maintain compatibility
> +		 * with the existing KVM behavior.
> +		 */
> +		if (new_n <= pmcr_n_limit)

Isn't this the only thing that actually matters?

> +			kvm->arch.pmcr_n = new_n;
> +	}
> +	mutex_unlock(&kvm->arch.config_lock);
> +
> +	/*
> +	 * Ignore writes to RES0 bits, read only bits that are cleared on
> +	 * vCPU reset, and writable bits that KVM doesn't support yet.
> +	 * (i.e. only PMCR.N and bits [7:0] are mutable from userspace)
> +	 * The LP bit is RES0 when FEAT_PMUv3p5 is not supported on the vCPU.
> +	 * But, we leave the bit as it is here, as the vCPU's PMUver might
> +	 * be changed later (NOTE: the bit will be cleared on first vCPU run
> +	 * if necessary).
> +	 */
> +	mutable_mask = (ARMV8_PMU_PMCR_MASK |
> +			(ARMV8_PMU_PMCR_N_MASK << ARMV8_PMU_PMCR_N_SHIFT));

Why is N part of the 'mutable' mask? The only bits that should make it
into the register are ARMV8_PMU_PMCR_MASK.

> +	val &= mutable_mask;
> +	val |= (__vcpu_sys_reg(vcpu, r->reg) & ~mutable_mask);
> +
> +	/* The LC bit is RES1 when AArch32 is not supported */
> +	if (!kvm_supports_32bit_el0())
> +		val |= ARMV8_PMU_PMCR_LC;
> +
> +	__vcpu_sys_reg(vcpu, r->reg) = val;
> +	return 0;

I think this should be rewritten as:

	val &= ARMV8_PMU_PMCR_MASK;
	/* The LC bit is RES1 when AArch32 is not supported */
	if (!kvm_supports_32bit_el0())
		val |= ARMV8_PMU_PMCR_LC;

	__vcpu_sys_reg(vcpu, r->reg) = val;
	return 0;

And that's it. Drop this 'mutable_mask' nonsense, as we should be
getting the correct value (merge of the per-vcpu register and VM-wide
N) since patch 4.

	M.

-- 
Without deviation from the norm, progress is not possible.

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

  reply	other threads:[~2023-10-23 13:00 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-20 21:40 [PATCH v8 00/13] KVM: arm64: PMU: Allow userspace to limit the number of PMCs on vCPU Raghavendra Rao Ananta
2023-10-20 21:40 ` Raghavendra Rao Ananta
2023-10-20 21:40 ` [PATCH v8 01/13] KVM: arm64: PMU: Introduce helpers to set the guest's PMU Raghavendra Rao Ananta
2023-10-20 21:40   ` Raghavendra Rao Ananta
2023-10-23 15:24   ` Sebastian Ott
2023-10-23 15:24     ` Sebastian Ott
2023-10-20 21:40 ` [PATCH v8 02/13] KVM: arm64: PMU: Set the default PMU for the guest before vCPU reset Raghavendra Rao Ananta
2023-10-20 21:40   ` Raghavendra Rao Ananta
2023-10-23 10:40   ` Marc Zyngier
2023-10-23 10:40     ` Marc Zyngier
2023-10-23 18:24     ` Oliver Upton
2023-10-23 18:24       ` Oliver Upton
2023-10-23 15:25   ` Sebastian Ott
2023-10-23 15:25     ` Sebastian Ott
2023-10-20 21:40 ` [PATCH v8 03/13] KVM: arm64: PMU: Add a helper to read a vCPU's PMCR_EL0 Raghavendra Rao Ananta
2023-10-20 21:40   ` Raghavendra Rao Ananta
2023-10-23 16:18   ` Sebastian Ott
2023-10-23 16:18     ` Sebastian Ott
2023-10-20 21:40 ` [PATCH v8 04/13] KVM: arm64: PMU: Set PMCR_EL0.N for vCPU based on the associated PMU Raghavendra Rao Ananta
2023-10-20 21:40   ` Raghavendra Rao Ananta
2023-10-23 11:50   ` Marc Zyngier
2023-10-23 11:50     ` Marc Zyngier
2023-10-23 16:20   ` Sebastian Ott
2023-10-23 16:20     ` Sebastian Ott
2023-10-24  9:22   ` Oliver Upton
2023-10-24  9:22     ` Oliver Upton
2023-10-20 21:40 ` [PATCH v8 05/13] KVM: arm64: Add {get,set}_user for PM{C,I}NTEN{SET,CLR}, PMOVS{SET,CLR} Raghavendra Rao Ananta
2023-10-20 21:40   ` Raghavendra Rao Ananta
2023-10-23 12:31   ` Marc Zyngier
2023-10-23 12:31     ` Marc Zyngier
2023-10-23 17:28     ` Raghavendra Rao Ananta
2023-10-23 17:28       ` Raghavendra Rao Ananta
2023-10-24  8:59   ` Oliver Upton
2023-10-24  8:59     ` Oliver Upton
2023-10-20 21:40 ` [PATCH v8 06/13] KVM: arm64: Sanitize PM{C,I}NTEN{SET,CLR}, PMOVS{SET,CLR} before first run Raghavendra Rao Ananta
2023-10-20 21:40   ` Raghavendra Rao Ananta
2023-10-23 12:42   ` Marc Zyngier
2023-10-23 12:42     ` Marc Zyngier
2023-10-23 17:42     ` Raghavendra Rao Ananta
2023-10-23 17:42       ` Raghavendra Rao Ananta
2023-10-23 18:07       ` Marc Zyngier
2023-10-23 18:07         ` Marc Zyngier
2023-10-24 19:56   ` kernel test robot
2023-10-20 21:40 ` [PATCH v8 07/13] KVM: arm64: PMU: Allow userspace to limit PMCR_EL0.N for the guest Raghavendra Rao Ananta
2023-10-20 21:40   ` Raghavendra Rao Ananta
2023-10-23 13:00   ` Marc Zyngier [this message]
2023-10-23 13:00     ` Marc Zyngier
2023-10-23 17:53     ` Raghavendra Rao Ananta
2023-10-23 17:53       ` Raghavendra Rao Ananta
2023-10-24 18:37   ` Oliver Upton
2023-10-24 18:37     ` Oliver Upton
2023-10-20 21:40 ` [PATCH v8 08/13] tools: Import arm_pmuv3.h Raghavendra Rao Ananta
2023-10-20 21:40   ` Raghavendra Rao Ananta
2023-10-20 21:40 ` [PATCH v8 09/13] KVM: selftests: aarch64: Introduce vpmu_counter_access test Raghavendra Rao Ananta
2023-10-20 21:40   ` Raghavendra Rao Ananta
2023-10-20 21:40 ` [PATCH v8 10/13] KVM: selftests: aarch64: vPMU register test for implemented counters Raghavendra Rao Ananta
2023-10-20 21:40   ` Raghavendra Rao Ananta
2023-10-20 21:40 ` [PATCH v8 11/13] KVM: selftests: aarch64: vPMU register test for unimplemented counters Raghavendra Rao Ananta
2023-10-20 21:40   ` Raghavendra Rao Ananta
2023-10-24 18:29   ` Oliver Upton
2023-10-24 18:29     ` Oliver Upton
2023-10-20 21:40 ` [PATCH v8 12/13] KVM: selftests: aarch64: vPMU test for validating user accesses Raghavendra Rao Ananta
2023-10-20 21:40   ` Raghavendra Rao Ananta
2023-10-20 21:40 ` [PATCH v8 13/13] KVM: selftests: aarch64: vPMU test for immutability Raghavendra Rao Ananta
2023-10-20 21:40   ` Raghavendra Rao Ananta
2023-10-24 10:36   ` Oliver Upton
2023-10-24 10:36     ` Oliver Upton
2023-10-23 13:09 ` [PATCH v8 00/13] KVM: arm64: PMU: Allow userspace to limit the number of PMCs on vCPU Marc Zyngier
2023-10-23 13:09   ` Marc Zyngier
2023-10-23 17:58   ` Raghavendra Rao Ananta
2023-10-23 17:58     ` Raghavendra Rao Ananta
2023-10-23 18:19     ` Marc Zyngier
2023-10-23 18:19       ` Marc Zyngier
2023-10-23 18:35 ` Marc Zyngier
2023-10-23 18:35   ` Marc Zyngier
2023-10-24 19:21   ` Oliver Upton
2023-10-24 19:21     ` Oliver Upton
2023-10-25  0:01 ` Oliver Upton
2023-10-25  0:01   ` Oliver Upton

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=86wmvd4hp9.wl-maz@kernel.org \
    --to=maz@kernel.org \
    --cc=alexandru.elisei@arm.com \
    --cc=coltonlewis@google.com \
    --cc=james.morse@arm.com \
    --cc=jingzhangos@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oliver.upton@linux.dev \
    --cc=pbonzini@redhat.com \
    --cc=rananta@google.com \
    --cc=reijiw@google.com \
    --cc=shahuang@redhat.com \
    --cc=suzuki.poulose@arm.com \
    --cc=yuzenghui@huawei.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.