* [PATCH] arm64: KVM: Don't generate UNDEF when LORegion feature is present
@ 2018-11-05 15:30 Marc Zyngier
2018-11-05 16:13 ` Mark Rutland
2018-11-06 8:26 ` Christoffer Dall
0 siblings, 2 replies; 3+ messages in thread
From: Marc Zyngier @ 2018-11-05 15:30 UTC (permalink / raw)
To: linux-arm-kernel
We currently hide the LORegion feature, and generate an UNDEF
if the guest dares using the corresponding registers. This is
a bit extreme, as ARMv8.1 guarantees the feature to be present.
The guest should check the feature register before doing anything,
but we could also give the guest some slack (read "allow the
guest to be a bit stupid").
So instead of unconditionnaly deliver an exception, let's
only do it when the host doesn't support LORegion at all (or
when the feature has been sanitized out), and treat the registers
as RAZ/WI otherwise (with the exception of LORID_EL1 being RO).
Fixes: cc33c4e20185 ("arm64/kvm: Prohibit guest LOR accesses")
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/kvm/sys_regs.c | 42 +++++++++++++++++++++++++--------------
1 file changed, 27 insertions(+), 15 deletions(-)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 22fbbdbece3c..1133b74065f1 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -314,12 +314,29 @@ static bool trap_raz_wi(struct kvm_vcpu *vcpu,
return read_zero(vcpu, p);
}
-static bool trap_undef(struct kvm_vcpu *vcpu,
- struct sys_reg_params *p,
- const struct sys_reg_desc *r)
+/*
+ * ARMv8.1 mandates at least a trivial LORegion implementation, where all the
+ * RW registers are RES0 (which we can implement as RAZ/WI). On an ARMv8.0
+ * system, these registers should UNDEF. LORID_EL1 being a RO register, we
+ * treat it separately.
+ */
+static bool trap_loregion(struct kvm_vcpu *vcpu,
+ struct sys_reg_params *p,
+ const struct sys_reg_desc *r)
{
- kvm_inject_undefined(vcpu);
- return false;
+ u64 val = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
+ u32 sr = sys_reg((u32)r->Op0, (u32)r->Op1,
+ (u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
+
+ if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))) {
+ kvm_inject_undefined(vcpu);
+ return false;
+ }
+
+ if (p->is_write && sr == SYS_LORID_EL1)
+ return write_to_read_only(vcpu, p, r);
+
+ return trap_raz_wi(vcpu, p, r);
}
static bool trap_oslsr_el1(struct kvm_vcpu *vcpu,
@@ -1040,11 +1057,6 @@ static u64 read_id_reg(struct sys_reg_desc const *r, bool raz)
kvm_debug("SVE unsupported for guests, suppressing\n");
val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT);
- } else if (id == SYS_ID_AA64MMFR1_EL1) {
- if (val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))
- kvm_debug("LORegions unsupported for guests, suppressing\n");
-
- val &= ~(0xfUL << ID_AA64MMFR1_LOR_SHIFT);
}
return val;
@@ -1330,11 +1342,11 @@ static const struct sys_reg_desc sys_reg_descs[] = {
{ SYS_DESC(SYS_MAIR_EL1), access_vm_reg, reset_unknown, MAIR_EL1 },
{ SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 },
- { SYS_DESC(SYS_LORSA_EL1), trap_undef },
- { SYS_DESC(SYS_LOREA_EL1), trap_undef },
- { SYS_DESC(SYS_LORN_EL1), trap_undef },
- { SYS_DESC(SYS_LORC_EL1), trap_undef },
- { SYS_DESC(SYS_LORID_EL1), trap_undef },
+ { SYS_DESC(SYS_LORSA_EL1), trap_loregion },
+ { SYS_DESC(SYS_LOREA_EL1), trap_loregion },
+ { SYS_DESC(SYS_LORN_EL1), trap_loregion },
+ { SYS_DESC(SYS_LORC_EL1), trap_loregion },
+ { SYS_DESC(SYS_LORID_EL1), trap_loregion },
{ SYS_DESC(SYS_VBAR_EL1), NULL, reset_val, VBAR_EL1, 0 },
{ SYS_DESC(SYS_DISR_EL1), NULL, reset_val, DISR_EL1, 0 },
--
2.19.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH] arm64: KVM: Don't generate UNDEF when LORegion feature is present
2018-11-05 15:30 [PATCH] arm64: KVM: Don't generate UNDEF when LORegion feature is present Marc Zyngier
@ 2018-11-05 16:13 ` Mark Rutland
2018-11-06 8:26 ` Christoffer Dall
1 sibling, 0 replies; 3+ messages in thread
From: Mark Rutland @ 2018-11-05 16:13 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Nov 05, 2018 at 03:30:26PM +0000, Marc Zyngier wrote:
> We currently hide the LORegion feature, and generate an UNDEF
> if the guest dares using the corresponding registers. This is
> a bit extreme, as ARMv8.1 guarantees the feature to be present.
>
> The guest should check the feature register before doing anything,
> but we could also give the guest some slack (read "allow the
> guest to be a bit stupid").
>
> So instead of unconditionnaly deliver an exception, let's
> only do it when the host doesn't support LORegion at all (or
> when the feature has been sanitized out), and treat the registers
> as RAZ/WI otherwise (with the exception of LORID_EL1 being RO).
>
> Fixes: cc33c4e20185 ("arm64/kvm: Prohibit guest LOR accesses")
> Suggested-by: Richard Henderson <richard.henderson@linaro.org>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
> arch/arm64/kvm/sys_regs.c | 42 +++++++++++++++++++++++++--------------
> 1 file changed, 27 insertions(+), 15 deletions(-)
>
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 22fbbdbece3c..1133b74065f1 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -314,12 +314,29 @@ static bool trap_raz_wi(struct kvm_vcpu *vcpu,
> return read_zero(vcpu, p);
> }
>
> -static bool trap_undef(struct kvm_vcpu *vcpu,
> - struct sys_reg_params *p,
> - const struct sys_reg_desc *r)
> +/*
> + * ARMv8.1 mandates at least a trivial LORegion implementation, where all the
> + * RW registers are RES0 (which we can implement as RAZ/WI). On an ARMv8.0
> + * system, these registers should UNDEF. LORID_EL1 being a RO register, we
> + * treat it separately.
> + */
> +static bool trap_loregion(struct kvm_vcpu *vcpu,
> + struct sys_reg_params *p,
> + const struct sys_reg_desc *r)
> {
> - kvm_inject_undefined(vcpu);
> - return false;
> + u64 val = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
> + u32 sr = sys_reg((u32)r->Op0, (u32)r->Op1,
> + (u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
> +
It might be worth factoring this into a helper (e.g. param_to_reg(p)),
since there are a few other places that this would help us to use
mnemonics for.
Either way:
Acked-by: Mark Rutland <mark.rutland@arm.com>
Mark.
> + if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))) {
> + kvm_inject_undefined(vcpu);
> + return false;
> + }
> +
> + if (p->is_write && sr == SYS_LORID_EL1)
> + return write_to_read_only(vcpu, p, r);
> +
> + return trap_raz_wi(vcpu, p, r);
> }
>
> static bool trap_oslsr_el1(struct kvm_vcpu *vcpu,
> @@ -1040,11 +1057,6 @@ static u64 read_id_reg(struct sys_reg_desc const *r, bool raz)
> kvm_debug("SVE unsupported for guests, suppressing\n");
>
> val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT);
> - } else if (id == SYS_ID_AA64MMFR1_EL1) {
> - if (val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))
> - kvm_debug("LORegions unsupported for guests, suppressing\n");
> -
> - val &= ~(0xfUL << ID_AA64MMFR1_LOR_SHIFT);
> }
>
> return val;
> @@ -1330,11 +1342,11 @@ static const struct sys_reg_desc sys_reg_descs[] = {
> { SYS_DESC(SYS_MAIR_EL1), access_vm_reg, reset_unknown, MAIR_EL1 },
> { SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 },
>
> - { SYS_DESC(SYS_LORSA_EL1), trap_undef },
> - { SYS_DESC(SYS_LOREA_EL1), trap_undef },
> - { SYS_DESC(SYS_LORN_EL1), trap_undef },
> - { SYS_DESC(SYS_LORC_EL1), trap_undef },
> - { SYS_DESC(SYS_LORID_EL1), trap_undef },
> + { SYS_DESC(SYS_LORSA_EL1), trap_loregion },
> + { SYS_DESC(SYS_LOREA_EL1), trap_loregion },
> + { SYS_DESC(SYS_LORN_EL1), trap_loregion },
> + { SYS_DESC(SYS_LORC_EL1), trap_loregion },
> + { SYS_DESC(SYS_LORID_EL1), trap_loregion },
>
> { SYS_DESC(SYS_VBAR_EL1), NULL, reset_val, VBAR_EL1, 0 },
> { SYS_DESC(SYS_DISR_EL1), NULL, reset_val, DISR_EL1, 0 },
> --
> 2.19.1
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH] arm64: KVM: Don't generate UNDEF when LORegion feature is present
2018-11-05 15:30 [PATCH] arm64: KVM: Don't generate UNDEF when LORegion feature is present Marc Zyngier
2018-11-05 16:13 ` Mark Rutland
@ 2018-11-06 8:26 ` Christoffer Dall
1 sibling, 0 replies; 3+ messages in thread
From: Christoffer Dall @ 2018-11-06 8:26 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Nov 05, 2018 at 03:30:26PM +0000, Marc Zyngier wrote:
> We currently hide the LORegion feature, and generate an UNDEF
> if the guest dares using the corresponding registers. This is
> a bit extreme, as ARMv8.1 guarantees the feature to be present.
>
> The guest should check the feature register before doing anything,
> but we could also give the guest some slack (read "allow the
> guest to be a bit stupid").
>
> So instead of unconditionnaly deliver an exception, let's
> only do it when the host doesn't support LORegion at all (or
> when the feature has been sanitized out), and treat the registers
> as RAZ/WI otherwise (with the exception of LORID_EL1 being RO).
>
> Fixes: cc33c4e20185 ("arm64/kvm: Prohibit guest LOR accesses")
> Suggested-by: Richard Henderson <richard.henderson@linaro.org>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Acked-by: Christoffer Dall <christoffer.dall@arm.com>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2018-11-06 8:26 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-11-05 15:30 [PATCH] arm64: KVM: Don't generate UNDEF when LORegion feature is present Marc Zyngier
2018-11-05 16:13 ` Mark Rutland
2018-11-06 8:26 ` Christoffer Dall
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).