[PATCH 22/37] KVM: arm64: Change 32-bit handling of VM system registers

Andrew Jones drjones at redhat.com
Mon Nov 13 08:25:51 PST 2017


On Thu, Oct 12, 2017 at 12:41:26PM +0200, Christoffer Dall wrote:
> We currently handle 32-bit accesses to trapped VM system registers using
> the 32-bit index into the coproc array on the vcpu structure, which is a
> union of the coprog array and the sysreg array.

coproc

> 
> Since all the 32-bit coproc indicies are created to correspond to the
> architectural mapping between 64-bit system registers and 32-bit
> coprocessor registers, and because the AArch64 system registers are the
> double in size of the AArch32 coprocessor registers, we can always find
> the system register entry that we must update by dividing the 32-bit
> coproc index by 2.
> 
> This is going to make our lives much easier when we have to start
> accessing system registers that uses deferred save/restore and might

use

> have to be read directly from the physical CPU.
> 
> Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
> ---
>  arch/arm64/include/asm/kvm_host.h |  8 --------
>  arch/arm64/kvm/sys_regs.c         | 20 +++++++++++++++-----
>  2 files changed, 15 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 5e09eb9..9f5761f 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -289,14 +289,6 @@ struct kvm_vcpu_arch {
>  #define vcpu_cp14(v,r)		((v)->arch.ctxt.copro[(r)])
>  #define vcpu_cp15(v,r)		((v)->arch.ctxt.copro[(r)])
>  
> -#ifdef CONFIG_CPU_BIG_ENDIAN
> -#define vcpu_cp15_64_high(v,r)	vcpu_cp15((v),(r))
> -#define vcpu_cp15_64_low(v,r)	vcpu_cp15((v),(r) + 1)
> -#else
> -#define vcpu_cp15_64_high(v,r)	vcpu_cp15((v),(r) + 1)
> -#define vcpu_cp15_64_low(v,r)	vcpu_cp15((v),(r))
> -#endif
> -
>  struct kvm_vm_stat {
>  	ulong remote_tlb_flush;
>  };
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index bb0e41b..dbe35fd 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -120,16 +120,26 @@ static bool access_vm_reg(struct kvm_vcpu *vcpu,
>  			  const struct sys_reg_desc *r)
>  {
>  	bool was_enabled = vcpu_has_cache_enabled(vcpu);
> +	u64 val;
> +	int reg = r->reg;
>  
>  	BUG_ON(!p->is_write);
>  
> -	if (!p->is_aarch32) {
> -		vcpu_sys_reg(vcpu, r->reg) = p->regval;
> +	/* See the 32bit mapping in kvm_host.h */
> +	if (p->is_aarch32)
> +		reg = r->reg / 2;
> +
> +	if (!p->is_aarch32 || !p->is_32bit) {
> +		val = p->regval;
>  	} else {
> -		if (!p->is_32bit)
> -			vcpu_cp15_64_high(vcpu, r->reg) = upper_32_bits(p->regval);
> -		vcpu_cp15_64_low(vcpu, r->reg) = lower_32_bits(p->regval);
> +		val = vcpu_sys_reg(vcpu, reg);
> +		if (r->reg % 2)
> +			val = (p->regval << 32) | (u64)lower_32_bits(val);
> +		else
> +			val = ((u64)upper_32_bits(val) << 32) |
> +				(u64)lower_32_bits(p->regval);
>  	}
> +	vcpu_sys_reg(vcpu, reg) = val;
>  
>  	kvm_toggle_cache(vcpu, was_enabled);
>  	return true;
> -- 
> 2.9.0
>

Reviewed-by: Andrew Jones <drjones at redhat.com>



More information about the linux-arm-kernel mailing list