From: Marc Zyngier <maz@kernel.org>
To: Oliver Upton <oupton@google.com>
Cc: kvm@vger.kernel.org, Peter Shier <pshier@google.com>,
kvmarm@lists.cs.columbia.edu,
linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH 2/3] KVM: arm64: Allow the guest to change the OS Lock status
Date: Fri, 29 Oct 2021 12:16:56 +0100 [thread overview]
Message-ID: <87mtms9j2v.wl-maz@kernel.org> (raw)
In-Reply-To: <20211029003202.158161-3-oupton@google.com>
Hi Oliver,
On Fri, 29 Oct 2021 01:32:01 +0100,
Oliver Upton <oupton@google.com> wrote:
>
> KVM diverges from the architecture in the way it handles the OSLAR_EL1
> register. While the architecture requires that the register be WO and
> that the OSLK bit is 1 out of reset, KVM implements the register as
> RAZ/WI.
>
> Align KVM with the architecture by permitting writes to OSLAR_EL1. Since
> the register is WO, stash the OS Lock status bit in OSLSR_EL1 and
> context switch the status between host/guest. Additionally, change the
> reset value of the OSLK bit to 1.
>
> Suggested-by: Marc Zyngier <maz@kernel.org>
> Signed-off-by: Oliver Upton <oupton@google.com>
> ---
> arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 5 +++++
> arch/arm64/kvm/sys_regs.c | 22 +++++++++++++++++++---
> 2 files changed, 24 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
> index de7e14c862e6..a65dab34f85b 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
> @@ -65,6 +65,8 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
> ctxt_sys_reg(ctxt, SP_EL1) = read_sysreg(sp_el1);
> ctxt_sys_reg(ctxt, ELR_EL1) = read_sysreg_el1(SYS_ELR);
> ctxt_sys_reg(ctxt, SPSR_EL1) = read_sysreg_el1(SYS_SPSR);
> +
> + ctxt_sys_reg(ctxt, OSLSR_EL1) = read_sysreg(oslsr_el1);
Why do we need to save/restore this outside of the debug context? It
seems to me that this is only needed if debug has been enabled by the
guest (KVM_ARM64_DEBUG_DIRTY being set), as we will have trapped the
OSLAR_EL1 access otherwise. I don't think we need to deal with this
register outside of this context, as debug exceptions cannot happen
otherwise (BRK excepted, of course).
> }
>
> static inline void __sysreg_save_el2_return_state(struct kvm_cpu_context *ctxt)
> @@ -149,6 +151,9 @@ static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
> write_sysreg(ctxt_sys_reg(ctxt, SP_EL1), sp_el1);
> write_sysreg_el1(ctxt_sys_reg(ctxt, ELR_EL1), SYS_ELR);
> write_sysreg_el1(ctxt_sys_reg(ctxt, SPSR_EL1), SYS_SPSR);
> +
> + /* restore OSLSR_EL1 by writing the OSLK bit to OSLAR_EL1 */
> + write_sysreg((ctxt_sys_reg(ctxt, OSLSR_EL1) >> 1) & 1, oslar_el1);
Please introduce some eye-pleasing bit definitions ("Here, there, and
everywhere", to quote someone famous).
> }
>
> static inline void __sysreg_restore_el2_return_state(struct kvm_cpu_context *ctxt)
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 0eb03e7508fe..0840ae081290 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -298,6 +298,22 @@ static bool trap_oslsr_el1(struct kvm_vcpu *vcpu,
> return true;
> }
>
> +static bool trap_oslar_el1(struct kvm_vcpu *vcpu,
> + struct sys_reg_params *p,
> + const struct sys_reg_desc *r)
> +{
> + u64 oslsr;
> +
> + if (!p->is_write)
> + return read_zero(vcpu, p);
This really should be an UNDEF (and it really should UNDEF in HW, but
we are being, maybe pointlessly, cautious).
> +
> + /* preserve all but the OSLK bit */
> + oslsr = vcpu_read_sys_reg(vcpu, OSLSR_EL1) & ~0x2ull;
> + vcpu_write_sys_reg(vcpu, OSLSR_EL1, oslsr | ((p->regval & 1) << 1));
> + return true;
> +}
> +
> +
Extra newline.
> static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu,
> struct sys_reg_params *p,
> const struct sys_reg_desc *r)
> @@ -1439,8 +1455,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
> DBG_BCR_BVR_WCR_WVR_EL1(15),
>
> { SYS_DESC(SYS_MDRAR_EL1), trap_raz_wi },
> - { SYS_DESC(SYS_OSLAR_EL1), trap_raz_wi },
> - { SYS_DESC(SYS_OSLSR_EL1), trap_oslsr_el1, reset_val, OSLSR_EL1, 0x00000008 },
> + { SYS_DESC(SYS_OSLAR_EL1), trap_oslar_el1 },
> + { SYS_DESC(SYS_OSLSR_EL1), trap_oslsr_el1, reset_val, OSLSR_EL1, 0x0000000A },
> { SYS_DESC(SYS_OSDLR_EL1), trap_raz_wi },
> { SYS_DESC(SYS_DBGPRCR_EL1), trap_raz_wi },
> { SYS_DESC(SYS_DBGCLAIMSET_EL1), trap_raz_wi },
> @@ -1912,7 +1928,7 @@ static const struct sys_reg_desc cp14_regs[] = {
>
> DBGBXVR(0),
> /* DBGOSLAR */
> - { Op1( 0), CRn( 1), CRm( 0), Op2( 4), trap_raz_wi },
> + { Op1( 0), CRn( 1), CRm( 0), Op2( 4), trap_oslar_el1 },
> DBGBXVR(1),
> /* DBGOSLSR */
> { Op1( 0), CRn( 1), CRm( 1), Op2( 4), trap_oslsr_el1, NULL, OSLSR_EL1 },
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
_______________________________________________
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: Marc Zyngier <maz@kernel.org>
To: Oliver Upton <oupton@google.com>
Cc: kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org,
James Morse <james.morse@arm.com>,
Alexandru Elisei <alexandru.elisei@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
linux-arm-kernel@lists.infradead.org,
Andrew Jones <drjones@redhat.com>,
Peter Shier <pshier@google.com>,
Ricardo Koller <ricarkol@google.com>,
Reiji Watanabe <reijiw@google.com>
Subject: Re: [PATCH 2/3] KVM: arm64: Allow the guest to change the OS Lock status
Date: Fri, 29 Oct 2021 12:16:56 +0100 [thread overview]
Message-ID: <87mtms9j2v.wl-maz@kernel.org> (raw)
In-Reply-To: <20211029003202.158161-3-oupton@google.com>
Hi Oliver,
On Fri, 29 Oct 2021 01:32:01 +0100,
Oliver Upton <oupton@google.com> wrote:
>
> KVM diverges from the architecture in the way it handles the OSLAR_EL1
> register. While the architecture requires that the register be WO and
> that the OSLK bit is 1 out of reset, KVM implements the register as
> RAZ/WI.
>
> Align KVM with the architecture by permitting writes to OSLAR_EL1. Since
> the register is WO, stash the OS Lock status bit in OSLSR_EL1 and
> context switch the status between host/guest. Additionally, change the
> reset value of the OSLK bit to 1.
>
> Suggested-by: Marc Zyngier <maz@kernel.org>
> Signed-off-by: Oliver Upton <oupton@google.com>
> ---
> arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 5 +++++
> arch/arm64/kvm/sys_regs.c | 22 +++++++++++++++++++---
> 2 files changed, 24 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
> index de7e14c862e6..a65dab34f85b 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
> @@ -65,6 +65,8 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
> ctxt_sys_reg(ctxt, SP_EL1) = read_sysreg(sp_el1);
> ctxt_sys_reg(ctxt, ELR_EL1) = read_sysreg_el1(SYS_ELR);
> ctxt_sys_reg(ctxt, SPSR_EL1) = read_sysreg_el1(SYS_SPSR);
> +
> + ctxt_sys_reg(ctxt, OSLSR_EL1) = read_sysreg(oslsr_el1);
Why do we need to save/restore this outside of the debug context? It
seems to me that this is only needed if debug has been enabled by the
guest (KVM_ARM64_DEBUG_DIRTY being set), as we will have trapped the
OSLAR_EL1 access otherwise. I don't think we need to deal with this
register outside of this context, as debug exceptions cannot happen
otherwise (BRK excepted, of course).
> }
>
> static inline void __sysreg_save_el2_return_state(struct kvm_cpu_context *ctxt)
> @@ -149,6 +151,9 @@ static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
> write_sysreg(ctxt_sys_reg(ctxt, SP_EL1), sp_el1);
> write_sysreg_el1(ctxt_sys_reg(ctxt, ELR_EL1), SYS_ELR);
> write_sysreg_el1(ctxt_sys_reg(ctxt, SPSR_EL1), SYS_SPSR);
> +
> + /* restore OSLSR_EL1 by writing the OSLK bit to OSLAR_EL1 */
> + write_sysreg((ctxt_sys_reg(ctxt, OSLSR_EL1) >> 1) & 1, oslar_el1);
Please introduce some eye-pleasing bit definitions ("Here, there, and
everywhere", to quote someone famous).
> }
>
> static inline void __sysreg_restore_el2_return_state(struct kvm_cpu_context *ctxt)
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 0eb03e7508fe..0840ae081290 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -298,6 +298,22 @@ static bool trap_oslsr_el1(struct kvm_vcpu *vcpu,
> return true;
> }
>
> +static bool trap_oslar_el1(struct kvm_vcpu *vcpu,
> + struct sys_reg_params *p,
> + const struct sys_reg_desc *r)
> +{
> + u64 oslsr;
> +
> + if (!p->is_write)
> + return read_zero(vcpu, p);
This really should be an UNDEF (and it really should UNDEF in HW, but
we are being, maybe pointlessly, cautious).
> +
> + /* preserve all but the OSLK bit */
> + oslsr = vcpu_read_sys_reg(vcpu, OSLSR_EL1) & ~0x2ull;
> + vcpu_write_sys_reg(vcpu, OSLSR_EL1, oslsr | ((p->regval & 1) << 1));
> + return true;
> +}
> +
> +
Extra newline.
> static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu,
> struct sys_reg_params *p,
> const struct sys_reg_desc *r)
> @@ -1439,8 +1455,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
> DBG_BCR_BVR_WCR_WVR_EL1(15),
>
> { SYS_DESC(SYS_MDRAR_EL1), trap_raz_wi },
> - { SYS_DESC(SYS_OSLAR_EL1), trap_raz_wi },
> - { SYS_DESC(SYS_OSLSR_EL1), trap_oslsr_el1, reset_val, OSLSR_EL1, 0x00000008 },
> + { SYS_DESC(SYS_OSLAR_EL1), trap_oslar_el1 },
> + { SYS_DESC(SYS_OSLSR_EL1), trap_oslsr_el1, reset_val, OSLSR_EL1, 0x0000000A },
> { SYS_DESC(SYS_OSDLR_EL1), trap_raz_wi },
> { SYS_DESC(SYS_DBGPRCR_EL1), trap_raz_wi },
> { SYS_DESC(SYS_DBGCLAIMSET_EL1), trap_raz_wi },
> @@ -1912,7 +1928,7 @@ static const struct sys_reg_desc cp14_regs[] = {
>
> DBGBXVR(0),
> /* DBGOSLAR */
> - { Op1( 0), CRn( 1), CRm( 0), Op2( 4), trap_raz_wi },
> + { Op1( 0), CRn( 1), CRm( 0), Op2( 4), trap_oslar_el1 },
> DBGBXVR(1),
> /* DBGOSLSR */
> { Op1( 0), CRn( 1), CRm( 1), Op2( 4), trap_oslsr_el1, NULL, OSLSR_EL1 },
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
WARNING: multiple messages have this Message-ID (diff)
From: Marc Zyngier <maz@kernel.org>
To: Oliver Upton <oupton@google.com>
Cc: kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org,
James Morse <james.morse@arm.com>,
Alexandru Elisei <alexandru.elisei@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
linux-arm-kernel@lists.infradead.org,
Andrew Jones <drjones@redhat.com>,
Peter Shier <pshier@google.com>,
Ricardo Koller <ricarkol@google.com>,
Reiji Watanabe <reijiw@google.com>
Subject: Re: [PATCH 2/3] KVM: arm64: Allow the guest to change the OS Lock status
Date: Fri, 29 Oct 2021 12:16:56 +0100 [thread overview]
Message-ID: <87mtms9j2v.wl-maz@kernel.org> (raw)
In-Reply-To: <20211029003202.158161-3-oupton@google.com>
Hi Oliver,
On Fri, 29 Oct 2021 01:32:01 +0100,
Oliver Upton <oupton@google.com> wrote:
>
> KVM diverges from the architecture in the way it handles the OSLAR_EL1
> register. While the architecture requires that the register be WO and
> that the OSLK bit is 1 out of reset, KVM implements the register as
> RAZ/WI.
>
> Align KVM with the architecture by permitting writes to OSLAR_EL1. Since
> the register is WO, stash the OS Lock status bit in OSLSR_EL1 and
> context switch the status between host/guest. Additionally, change the
> reset value of the OSLK bit to 1.
>
> Suggested-by: Marc Zyngier <maz@kernel.org>
> Signed-off-by: Oliver Upton <oupton@google.com>
> ---
> arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 5 +++++
> arch/arm64/kvm/sys_regs.c | 22 +++++++++++++++++++---
> 2 files changed, 24 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
> index de7e14c862e6..a65dab34f85b 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
> @@ -65,6 +65,8 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
> ctxt_sys_reg(ctxt, SP_EL1) = read_sysreg(sp_el1);
> ctxt_sys_reg(ctxt, ELR_EL1) = read_sysreg_el1(SYS_ELR);
> ctxt_sys_reg(ctxt, SPSR_EL1) = read_sysreg_el1(SYS_SPSR);
> +
> + ctxt_sys_reg(ctxt, OSLSR_EL1) = read_sysreg(oslsr_el1);
Why do we need to save/restore this outside of the debug context? It
seems to me that this is only needed if debug has been enabled by the
guest (KVM_ARM64_DEBUG_DIRTY being set), as we will have trapped the
OSLAR_EL1 access otherwise. I don't think we need to deal with this
register outside of this context, as debug exceptions cannot happen
otherwise (BRK excepted, of course).
> }
>
> static inline void __sysreg_save_el2_return_state(struct kvm_cpu_context *ctxt)
> @@ -149,6 +151,9 @@ static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
> write_sysreg(ctxt_sys_reg(ctxt, SP_EL1), sp_el1);
> write_sysreg_el1(ctxt_sys_reg(ctxt, ELR_EL1), SYS_ELR);
> write_sysreg_el1(ctxt_sys_reg(ctxt, SPSR_EL1), SYS_SPSR);
> +
> + /* restore OSLSR_EL1 by writing the OSLK bit to OSLAR_EL1 */
> + write_sysreg((ctxt_sys_reg(ctxt, OSLSR_EL1) >> 1) & 1, oslar_el1);
Please introduce some eye-pleasing bit definitions ("Here, there, and
everywhere", to quote someone famous).
> }
>
> static inline void __sysreg_restore_el2_return_state(struct kvm_cpu_context *ctxt)
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 0eb03e7508fe..0840ae081290 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -298,6 +298,22 @@ static bool trap_oslsr_el1(struct kvm_vcpu *vcpu,
> return true;
> }
>
> +static bool trap_oslar_el1(struct kvm_vcpu *vcpu,
> + struct sys_reg_params *p,
> + const struct sys_reg_desc *r)
> +{
> + u64 oslsr;
> +
> + if (!p->is_write)
> + return read_zero(vcpu, p);
This really should be an UNDEF (and it really should UNDEF in HW, but
we are being, maybe pointlessly, cautious).
> +
> + /* preserve all but the OSLK bit */
> + oslsr = vcpu_read_sys_reg(vcpu, OSLSR_EL1) & ~0x2ull;
> + vcpu_write_sys_reg(vcpu, OSLSR_EL1, oslsr | ((p->regval & 1) << 1));
> + return true;
> +}
> +
> +
Extra newline.
> static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu,
> struct sys_reg_params *p,
> const struct sys_reg_desc *r)
> @@ -1439,8 +1455,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
> DBG_BCR_BVR_WCR_WVR_EL1(15),
>
> { SYS_DESC(SYS_MDRAR_EL1), trap_raz_wi },
> - { SYS_DESC(SYS_OSLAR_EL1), trap_raz_wi },
> - { SYS_DESC(SYS_OSLSR_EL1), trap_oslsr_el1, reset_val, OSLSR_EL1, 0x00000008 },
> + { SYS_DESC(SYS_OSLAR_EL1), trap_oslar_el1 },
> + { SYS_DESC(SYS_OSLSR_EL1), trap_oslsr_el1, reset_val, OSLSR_EL1, 0x0000000A },
> { SYS_DESC(SYS_OSDLR_EL1), trap_raz_wi },
> { SYS_DESC(SYS_DBGPRCR_EL1), trap_raz_wi },
> { SYS_DESC(SYS_DBGCLAIMSET_EL1), trap_raz_wi },
> @@ -1912,7 +1928,7 @@ static const struct sys_reg_desc cp14_regs[] = {
>
> DBGBXVR(0),
> /* DBGOSLAR */
> - { Op1( 0), CRn( 1), CRm( 0), Op2( 4), trap_raz_wi },
> + { Op1( 0), CRn( 1), CRm( 0), Op2( 4), trap_oslar_el1 },
> DBGBXVR(1),
> /* DBGOSLSR */
> { Op1( 0), CRn( 1), CRm( 1), Op2( 4), trap_oslsr_el1, NULL, OSLSR_EL1 },
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
next prev parent reply other threads:[~2021-10-29 11:17 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-29 0:31 [PATCH 0/3] KVM: arm64: Fixes for the exposed debug architecture Oliver Upton
2021-10-29 0:31 ` Oliver Upton
2021-10-29 0:31 ` Oliver Upton
2021-10-29 0:32 ` [PATCH 1/3] KVM: arm64: Stash OSLSR_EL1 in the cpu context Oliver Upton
2021-10-29 0:32 ` Oliver Upton
2021-10-29 0:32 ` Oliver Upton
2021-10-29 11:27 ` Marc Zyngier
2021-10-29 11:27 ` Marc Zyngier
2021-10-29 11:27 ` Marc Zyngier
2021-10-29 0:32 ` [PATCH 2/3] KVM: arm64: Allow the guest to change the OS Lock status Oliver Upton
2021-10-29 0:32 ` Oliver Upton
2021-10-29 0:32 ` Oliver Upton
2021-10-29 11:16 ` Marc Zyngier [this message]
2021-10-29 11:16 ` Marc Zyngier
2021-10-29 11:16 ` Marc Zyngier
2021-10-29 0:32 ` [PATCH 3/3] KVM: arm64: Raise KVM's reported debug architecture to v8.2 Oliver Upton
2021-10-29 0:32 ` Oliver Upton
2021-10-29 0:32 ` Oliver Upton
2021-10-29 11:31 ` Marc Zyngier
2021-10-29 11:31 ` Marc Zyngier
2021-10-29 11:31 ` Marc Zyngier
2021-10-29 18:18 ` Oliver Upton
2021-10-29 18:18 ` Oliver Upton
2021-10-29 18:18 ` Oliver Upton
2021-11-01 10:21 ` Marc Zyngier
2021-11-01 10:21 ` Marc Zyngier
2021-11-01 10:21 ` 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=87mtms9j2v.wl-maz@kernel.org \
--to=maz@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=oupton@google.com \
--cc=pshier@google.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.