Re: [PATCH v7 16/27] KVM: arm64: Factor out core register ID enumeration

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Apr 02, 2019 at 03:41:56AM +0100, Marc Zyngier wrote:
> On Fri, 29 Mar 2019 13:00:41 +0000,
> Dave Martin <Dave.Martin@xxxxxxx> wrote:
> > 
> > In preparation for adding logic to filter out some KVM_REG_ARM_CORE
> > registers from the KVM_GET_REG_LIST output, this patch factors out
> > the core register enumeration into a separate function and rebuilds
> > num_core_regs() on top of it.
> > 
> > This may be a little more expensive (depending on how good a job
> > the compiler does of specialising the code), but KVM_GET_REG_LIST
> > is not a hot path.
> > 
> > This will make it easier to consolidate ID filtering code in one
> > place.
> > 
> > No functional change.
> > 
> > Signed-off-by: Dave Martin <Dave.Martin@xxxxxxx>
> > Reviewed-by: Julien Thierry <julien.thierry@xxxxxxx>
> > Tested-by: zhang.lei <zhang.lei@xxxxxxxxxxxxxx>
> > 
> > ---
> > 
> > Changes since v5:
> > 
> >  * New patch.
> > 
> >    This reimplements part of the separately-posted patch "KVM: arm64:
> >    Factor out KVM_GET_REG_LIST core register enumeration", minus aspects
> >    that potentially break the ABI.
> > 
> >    As a result, the opportunity to truly consolidate all the ID reg
> >    filtering in one place is deliberately left on the floor, for now.
> >    This will be addressed in a separate series later on.
> > ---
> >  arch/arm64/kvm/guest.c | 33 +++++++++++++++++++++++++--------
> >  1 file changed, 25 insertions(+), 8 deletions(-)
> > 
> > diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
> > index 3e38eb2..a391a61 100644
> > --- a/arch/arm64/kvm/guest.c
> > +++ b/arch/arm64/kvm/guest.c

[...]

> > @@ -276,15 +296,12 @@ unsigned long kvm_arm_num_regs(struct kvm_vcpu *vcpu)
> >   */
> >  int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
> >  {
> > -	unsigned int i;
> > -	const u64 core_reg = KVM_REG_ARM64 | KVM_REG_SIZE_U64 | KVM_REG_ARM_CORE;
> >  	int ret;
> >  
> > -	for (i = 0; i < sizeof(struct kvm_regs) / sizeof(__u32); i++) {
> > -		if (put_user(core_reg | i, uindices))
> > -			return -EFAULT;
> > -		uindices++;
> > -	}
> > +	ret = kvm_arm_copy_core_reg_indices(uindices);
> > +	if (ret)
> > +		return ret;
> > +	uindices += ret;
> 
> Interesting snippet. Given that most implementations have at least one
> register, this can hardly work. Please do test things with QEMU, and
> not only kvmtool which obviously doesn't exercise this path.

My bad: this used to work to do the right thing, but I broke it when
splitting up [1] for v6 to avoid the dependency.

kvm_arm_copy_core_reg_indices() used to take &uindices and update it
directly, returning 0 on success instead of the number of registers.
But this seemed less consistent with the way the other functions are
called.

> For the sake of getting -next back to a vaguely usable state, I've now
> queued the following patch on top.
> 
> 	M.
> 
> From 832401c8912680ee56dc5cb6ab101266b3db416a Mon Sep 17 00:00:00 2001
> From: Marc Zyngier <marc.zyngier@xxxxxxx>
> Date: Tue, 2 Apr 2019 03:28:39 +0100
> Subject: [PATCH] arm64: KVM: Fix system register enumeration
> 
> The introduction of the SVE registers to userspace started with a
> refactoring of the way we expose any register via the ONE_REG
> interface.
> 
> Unfortunately, this change doesn't exactly behave as expected
> if the number of registers is non-zero and consider everything
> to be an error. The visible result is that QEMU barfs very early
> when creating vcpus.
> 
> Make sure we only exit early in case there is an actual error, rather
> than a positive number of registers...
> 
> be25bbb392fa ("KVM: arm64: Factor out core register ID enumeration")
> Signed-off-by: Marc Zyngier <marc.zyngier@xxxxxxx>
> ---
>  arch/arm64/kvm/guest.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
> index 086ab0508d69..4f7b26bbf671 100644
> --- a/arch/arm64/kvm/guest.c
> +++ b/arch/arm64/kvm/guest.c
> @@ -604,22 +604,22 @@ int kvm_arm_copy_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
>  	int ret;
>  
>  	ret = copy_core_reg_indices(vcpu, uindices);
> -	if (ret)
> +	if (ret < 0)
>  		return ret;
>  	uindices += ret;
>  
>  	ret = copy_sve_reg_indices(vcpu, uindices);
> -	if (ret)
> +	if (ret < 0)
>  		return ret;
>  	uindices += ret;

^ Ack

>  	ret = kvm_arm_copy_fw_reg_indices(vcpu, uindices);
> -	if (ret)
> +	if (ret < 0)
>  		return ret;
>  	uindices += kvm_arm_get_fw_num_regs(vcpu);
>  
>  	ret = copy_timer_indices(vcpu, uindices);
> -	if (ret)
> +	if (ret < 0)
>  		return ret;
>  	uindices += NUM_TIMER_REGS;

For these two, the interface is not really the same.  These don't
return the number of registers, so return 0 on success.  "< 0" here
could be a trap for the future, though the risk looks low.

I can have a go at some rework on top to make this more consistent,
but I'd rather not muddy the water further for the moment.

Any view on that?

Cheers
---Dave
_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm



[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux