From: Marc Zyngier <maz@kernel.org>
To: Sebastian Ott <sebott@redhat.com>
Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
linux-kernel@vger.kernel.org,
Oliver Upton <oliver.upton@linux.dev>,
James Morse <james.morse@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>
Subject: Re: [PATCH 2/4] KVM: arm64: maintain per VM value for CTR_EL0
Date: Sat, 13 Apr 2024 11:04:11 +0100 [thread overview]
Message-ID: <86frvpshno.wl-maz@kernel.org> (raw)
In-Reply-To: <20240405120108.11844-3-sebott@redhat.com>
On Fri, 05 Apr 2024 13:01:06 +0100,
Sebastian Ott <sebott@redhat.com> wrote:
>
> In preparation for CTR_EL0 emulation maintain a per VM for this
> register and use it where appropriate.
>
> Signed-off-by: Sebastian Ott <sebott@redhat.com>
> ---
> arch/arm64/include/asm/kvm_host.h | 1 +
> arch/arm64/kvm/sys_regs.c | 22 +++++++++++++++-------
> 2 files changed, 16 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 9e8a496fb284..481216febb46 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -318,6 +318,7 @@ struct kvm_arch {
>
> /* PMCR_EL0.N value for the guest */
> u8 pmcr_n;
> + u64 ctr_el0;
>
> /* Iterator for idreg debugfs */
> u8 idreg_debugfs_iter;
Please consider the alignment of the fields. This leaves a 7 byte hole
that could be avoided (yes, I'm on a mission to reduce the size of the
various structures, because they are absolute pigs).
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 131f5b0ca2b9..4d29b1a0842d 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -215,13 +215,21 @@ void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
> /* CSSELR values; used to index KVM_REG_ARM_DEMUX_ID_CCSIDR */
> #define CSSELR_MAX 14
>
> +static u64 kvm_get_ctr_el0(struct kvm *kvm)
> +{
> + if (kvm->arch.ctr_el0)
> + return kvm->arch.ctr_el0;
Is this relying on some bits not being 0?
> +
> + return read_sanitised_ftr_reg(SYS_CTR_EL0);
Why isn't the shadow value always populated?
> +}
> +
> /*
> * Returns the minimum line size for the selected cache, expressed as
> * Log2(bytes).
> */
> -static u8 get_min_cache_line_size(bool icache)
> +static u8 get_min_cache_line_size(struct kvm *kvm, bool icache)
> {
> - u64 ctr = read_sanitised_ftr_reg(SYS_CTR_EL0);
> + u64 ctr = kvm_get_ctr_el0(kvm);
> u8 field;
>
> if (icache)
> @@ -248,7 +256,7 @@ static u32 get_ccsidr(struct kvm_vcpu *vcpu, u32 csselr)
> if (vcpu->arch.ccsidr)
> return vcpu->arch.ccsidr[csselr];
>
> - line_size = get_min_cache_line_size(csselr & CSSELR_EL1_InD);
> + line_size = get_min_cache_line_size(vcpu->kvm, csselr & CSSELR_EL1_InD);
>
> /*
> * Fabricate a CCSIDR value as the overriding value does not exist.
> @@ -283,7 +291,7 @@ static int set_ccsidr(struct kvm_vcpu *vcpu, u32 csselr, u32 val)
> u32 i;
>
> if ((val & CCSIDR_EL1_RES0) ||
> - line_size < get_min_cache_line_size(csselr & CSSELR_EL1_InD))
> + line_size < get_min_cache_line_size(vcpu->kvm, csselr & CSSELR_EL1_InD))
> return -EINVAL;
>
> if (!ccsidr) {
> @@ -1862,7 +1870,7 @@ static bool access_ctr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> if (p->is_write)
> return write_to_read_only(vcpu, p, r);
>
> - p->regval = read_sanitised_ftr_reg(SYS_CTR_EL0);
> + p->regval = kvm_get_ctr_el0(vcpu->kvm);
> return true;
> }
>
> @@ -1882,7 +1890,7 @@ static bool access_clidr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> */
> static u64 reset_clidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
> {
> - u64 ctr_el0 = read_sanitised_ftr_reg(SYS_CTR_EL0);
> + u64 ctr_el0 = kvm_get_ctr_el0(vcpu->kvm);
> u64 clidr;
> u8 loc;
>
> @@ -1935,7 +1943,7 @@ static u64 reset_clidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
> static int set_clidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
> u64 val)
> {
> - u64 ctr_el0 = read_sanitised_ftr_reg(SYS_CTR_EL0);
> + u64 ctr_el0 = kvm_get_ctr_el0(vcpu->kvm);
> u64 idc = !CLIDR_LOC(val) || (!CLIDR_LOUIS(val) && !CLIDR_LOUU(val));
>
> if ((val & CLIDR_EL1_RES0) || (!(ctr_el0 & CTR_EL0_IDC) && idc))
Thanks,
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: Sebastian Ott <sebott@redhat.com>
Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
linux-kernel@vger.kernel.org,
Oliver Upton <oliver.upton@linux.dev>,
James Morse <james.morse@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>
Subject: Re: [PATCH 2/4] KVM: arm64: maintain per VM value for CTR_EL0
Date: Sat, 13 Apr 2024 11:04:11 +0100 [thread overview]
Message-ID: <86frvpshno.wl-maz@kernel.org> (raw)
In-Reply-To: <20240405120108.11844-3-sebott@redhat.com>
On Fri, 05 Apr 2024 13:01:06 +0100,
Sebastian Ott <sebott@redhat.com> wrote:
>
> In preparation for CTR_EL0 emulation maintain a per VM for this
> register and use it where appropriate.
>
> Signed-off-by: Sebastian Ott <sebott@redhat.com>
> ---
> arch/arm64/include/asm/kvm_host.h | 1 +
> arch/arm64/kvm/sys_regs.c | 22 +++++++++++++++-------
> 2 files changed, 16 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 9e8a496fb284..481216febb46 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -318,6 +318,7 @@ struct kvm_arch {
>
> /* PMCR_EL0.N value for the guest */
> u8 pmcr_n;
> + u64 ctr_el0;
>
> /* Iterator for idreg debugfs */
> u8 idreg_debugfs_iter;
Please consider the alignment of the fields. This leaves a 7 byte hole
that could be avoided (yes, I'm on a mission to reduce the size of the
various structures, because they are absolute pigs).
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 131f5b0ca2b9..4d29b1a0842d 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -215,13 +215,21 @@ void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
> /* CSSELR values; used to index KVM_REG_ARM_DEMUX_ID_CCSIDR */
> #define CSSELR_MAX 14
>
> +static u64 kvm_get_ctr_el0(struct kvm *kvm)
> +{
> + if (kvm->arch.ctr_el0)
> + return kvm->arch.ctr_el0;
Is this relying on some bits not being 0?
> +
> + return read_sanitised_ftr_reg(SYS_CTR_EL0);
Why isn't the shadow value always populated?
> +}
> +
> /*
> * Returns the minimum line size for the selected cache, expressed as
> * Log2(bytes).
> */
> -static u8 get_min_cache_line_size(bool icache)
> +static u8 get_min_cache_line_size(struct kvm *kvm, bool icache)
> {
> - u64 ctr = read_sanitised_ftr_reg(SYS_CTR_EL0);
> + u64 ctr = kvm_get_ctr_el0(kvm);
> u8 field;
>
> if (icache)
> @@ -248,7 +256,7 @@ static u32 get_ccsidr(struct kvm_vcpu *vcpu, u32 csselr)
> if (vcpu->arch.ccsidr)
> return vcpu->arch.ccsidr[csselr];
>
> - line_size = get_min_cache_line_size(csselr & CSSELR_EL1_InD);
> + line_size = get_min_cache_line_size(vcpu->kvm, csselr & CSSELR_EL1_InD);
>
> /*
> * Fabricate a CCSIDR value as the overriding value does not exist.
> @@ -283,7 +291,7 @@ static int set_ccsidr(struct kvm_vcpu *vcpu, u32 csselr, u32 val)
> u32 i;
>
> if ((val & CCSIDR_EL1_RES0) ||
> - line_size < get_min_cache_line_size(csselr & CSSELR_EL1_InD))
> + line_size < get_min_cache_line_size(vcpu->kvm, csselr & CSSELR_EL1_InD))
> return -EINVAL;
>
> if (!ccsidr) {
> @@ -1862,7 +1870,7 @@ static bool access_ctr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> if (p->is_write)
> return write_to_read_only(vcpu, p, r);
>
> - p->regval = read_sanitised_ftr_reg(SYS_CTR_EL0);
> + p->regval = kvm_get_ctr_el0(vcpu->kvm);
> return true;
> }
>
> @@ -1882,7 +1890,7 @@ static bool access_clidr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> */
> static u64 reset_clidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
> {
> - u64 ctr_el0 = read_sanitised_ftr_reg(SYS_CTR_EL0);
> + u64 ctr_el0 = kvm_get_ctr_el0(vcpu->kvm);
> u64 clidr;
> u8 loc;
>
> @@ -1935,7 +1943,7 @@ static u64 reset_clidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
> static int set_clidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
> u64 val)
> {
> - u64 ctr_el0 = read_sanitised_ftr_reg(SYS_CTR_EL0);
> + u64 ctr_el0 = kvm_get_ctr_el0(vcpu->kvm);
> u64 idc = !CLIDR_LOC(val) || (!CLIDR_LOUIS(val) && !CLIDR_LOUU(val));
>
> if ((val & CLIDR_EL1_RES0) || (!(ctr_el0 & CTR_EL0_IDC) && idc))
Thanks,
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
next prev parent reply other threads:[~2024-04-13 10:04 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-05 12:01 [PATCH 0/4] KVM: arm64: emulation for CTR_EL0 Sebastian Ott
2024-04-05 12:01 ` Sebastian Ott
2024-04-05 12:01 ` [PATCH 1/4] KVM: arm64: change return value in arm64_check_features() Sebastian Ott
2024-04-05 12:01 ` Sebastian Ott
2024-04-05 12:01 ` [PATCH 2/4] KVM: arm64: maintain per VM value for CTR_EL0 Sebastian Ott
2024-04-05 12:01 ` Sebastian Ott
2024-04-13 10:04 ` Marc Zyngier [this message]
2024-04-13 10:04 ` Marc Zyngier
2024-04-13 13:05 ` Sebastian Ott
2024-04-13 13:05 ` Sebastian Ott
2024-04-05 12:01 ` [PATCH 3/4] KVM: arm64: add emulation for CTR_EL0 register Sebastian Ott
2024-04-05 12:01 ` Sebastian Ott
2024-04-13 10:19 ` Marc Zyngier
2024-04-13 10:19 ` Marc Zyngier
2024-04-13 13:50 ` Sebastian Ott
2024-04-13 13:50 ` Sebastian Ott
2024-04-14 8:35 ` Marc Zyngier
2024-04-14 8:35 ` Marc Zyngier
2024-04-05 12:01 ` [PATCH 4/4] KVM: arm64: show writable masks for feature registers Sebastian Ott
2024-04-05 12:01 ` Sebastian Ott
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=86frvpshno.wl-maz@kernel.org \
--to=maz@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=james.morse@arm.com \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=oliver.upton@linux.dev \
--cc=sebott@redhat.com \
--cc=suzuki.poulose@arm.com \
--cc=will@kernel.org \
/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.