[PATCH] arm64/kvm: Prohibit guest LOR accesses

Mark Rutland mark.rutland at arm.com
Tue Feb 13 04:39:37 PST 2018


On Tue, Feb 13, 2018 at 11:27:42AM +0100, Christoffer Dall wrote:
> Hi Mark,

Hi Christoffer,

> On Mon, Feb 12, 2018 at 11:14:24AM +0000, Mark Rutland wrote:
> > We don't currently limit guest accesses to the LOR registers, which we
> > neither virtualize nor context-switch. As such, guests are provided with
> > unusable information/controls, and are not isolated from each other (or
> > the host).
> > 
> > To prevent these issues, we can trap register accesses and present the
> > illusion that no LORegions are implemented.
> 
> Shouldn't we then also hide this from the ID register similar to what we
> do for SVE at the moment, using something like this (untested):
> 
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index a828a209716f..b7ee414aee67 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -1064,6 +1064,12 @@ static u64 read_id_reg(struct sys_reg_desc const *r, bool raz)
>  				    task_pid_nr(current));
>  
>  		val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT);
> +	} else if (id == SYS_ID_AA64MMFR1_EL) {
> +		if (val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))
> +			pr_err_once("kvm [%i]: LORegions unsupported for guests, suppressing\n",
> +				    task_pid_nr(current));
> +
> +		val &= ~(0xfUL << ID_AA64MMFR1_LOR_SHIFT);
>  	}
>  
>  	return val;

Sure. With that, it would make sense for the trapped LOR* register
accesses to UNDEF, as they logically shouldn't exist.

[...]

> > diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> > index 50a43c7b97ca..67b10b7a07bf 100644
> > --- a/arch/arm64/kvm/sys_regs.c
> > +++ b/arch/arm64/kvm/sys_regs.c
> > @@ -175,6 +175,17 @@ static bool trap_raz_wi(struct kvm_vcpu *vcpu,
> >  		return read_zero(vcpu, p);
> >  }
> >  
> > +static bool trap_raz_ro(struct kvm_vcpu *vcpu,
> > +			struct sys_reg_params *p,
> > +			const struct sys_reg_desc *r)
> > +{
> > +	if (!p->is_write)
> > +		return read_zero(vcpu, p);
> > +
> > +	kvm_inject_undefined(vcpu);
> > +	return false;
> > +}
> > +
> 
> I'm a little unclear if this is stricly the right thing to do.  I can't
> seem to find anything specific about writes to this register (which has
> some text about RW fields but only specifies it can be *read* with an
> MRS instruction), so it seems to me that this should either be
> trap_raz_wi(), or call write_to_read_only() if we expect a write to
> undef at EL1 rather than trap to EL2.  On the other hand, if the
> architecture is unclear, then we're at least enforcing one
> interpretation here I suppose.

Having looked at the ARM ARM, I think write_to_read_only() is the right
thing to do.

It's not clear to me whether HCR_EL2.TLOR traps writes to LORID_EL1, or
leaves these UNDEFINED at EL1. In the description of traps and enables
it's stated that HCR_EL2.TLOR traps "Non-secure accesses to this
register from EL1", which could be read to mean either. I'll see if I
can get to the bottom of that.

I don't think trap_raz_wi(), as LORID_EL1 is never RW at EL1, and a
write wound UNDEF were HCR_EL2.TLOR clear.

Thanks,
Mark.



More information about the linux-arm-kernel mailing list