On Wed, Jan 17, 2018 at 06:22:29PM +0000, Julien Thierry wrote: > Hi, > > On 12/01/18 12:07, Christoffer Dall wrote: > >32-bit registers are not used by a 64-bit host kernel and can be > >deferred, but we need to rework the accesses to this register to access > >the latest value depending on whether or not guest system registers are > >loaded on the CPU or only reside in memory. > > > >Signed-off-by: Christoffer Dall <christoffer.dall@xxxxxxxxxx> > > Reviewed-by: Julien Thierry <julien.thierry@xxxxxxx> > > >--- > > arch/arm64/include/asm/kvm_emulate.h | 32 +++++------------- > > arch/arm64/kvm/regmap.c | 65 ++++++++++++++++++++++++++---------- > > arch/arm64/kvm/sys_regs.c | 6 ++-- > > 3 files changed, 60 insertions(+), 43 deletions(-) > > > > [...] > > >diff --git a/arch/arm64/kvm/regmap.c b/arch/arm64/kvm/regmap.c > >index bbc6ae32e4af..3f65098aff8d 100644 > >--- a/arch/arm64/kvm/regmap.c > >+++ b/arch/arm64/kvm/regmap.c > >@@ -141,28 +141,59 @@ unsigned long *vcpu_reg32(const struct kvm_vcpu *vcpu, u8 reg_num) > > /* > > * Return the SPSR for the current mode of the virtual CPU. > > */ > >-unsigned long *vcpu_spsr32(const struct kvm_vcpu *vcpu) > >+static int vcpu_spsr32_mode(const struct kvm_vcpu *vcpu) > > { > > unsigned long mode = *vcpu_cpsr(vcpu) & COMPAT_PSR_MODE_MASK; > > switch (mode) { > >- case COMPAT_PSR_MODE_SVC: > >- mode = KVM_SPSR_SVC; > >- break; > >- case COMPAT_PSR_MODE_ABT: > >- mode = KVM_SPSR_ABT; > >- break; > >- case COMPAT_PSR_MODE_UND: > >- mode = KVM_SPSR_UND; > >- break; > >- case COMPAT_PSR_MODE_IRQ: > >- mode = KVM_SPSR_IRQ; > >- break; > >- case COMPAT_PSR_MODE_FIQ: > >- mode = KVM_SPSR_FIQ; > >- break; > >+ case COMPAT_PSR_MODE_SVC: return KVM_SPSR_SVC; > >+ case COMPAT_PSR_MODE_ABT: return KVM_SPSR_ABT; > >+ case COMPAT_PSR_MODE_UND: return KVM_SPSR_UND; > >+ case COMPAT_PSR_MODE_IRQ: return KVM_SPSR_IRQ; > >+ case COMPAT_PSR_MODE_FIQ: return KVM_SPSR_FIQ; > >+ default: BUG(); > >+ } > >+} > >+ > >+unsigned long vcpu_read_spsr32(const struct kvm_vcpu *vcpu) > >+{ > >+ int spsr_idx = vcpu_spsr32_mode(vcpu); > >+ > >+ if (!vcpu->arch.sysregs_loaded_on_cpu) > >+ return vcpu_gp_regs(vcpu)->spsr[spsr_idx]; > >+ > >+ switch (spsr_idx) { > >+ case KVM_SPSR_SVC: > >+ return read_sysreg_el1(spsr); > >+ case KVM_SPSR_ABT: > >+ return read_sysreg(spsr_abt); > >+ case KVM_SPSR_UND: > >+ return read_sysreg(spsr_und); > >+ case KVM_SPSR_IRQ: > >+ return read_sysreg(spsr_irq); > >+ case KVM_SPSR_FIQ: > >+ return read_sysreg(spsr_fiq); > > default: > > BUG(); > > Nit: > > Since the BUG() is in vcpu_spsr32_mode now, you can probably remove it here > (or add it to vcpu_write_sprsr32 for consistency). > > > } Yes, I'll remove it. Thanks, -Christoffer > >+} > >- return (unsigned long *)&vcpu_gp_regs(vcpu)->spsr[mode]; > >+void vcpu_write_spsr32(struct kvm_vcpu *vcpu, unsigned long v) > >+{ > >+ int spsr_idx = vcpu_spsr32_mode(vcpu); > >+ > >+ if (!vcpu->arch.sysregs_loaded_on_cpu) > >+ vcpu_gp_regs(vcpu)->spsr[spsr_idx] = v; > >+ > >+ switch (spsr_idx) { > >+ case KVM_SPSR_SVC: > >+ write_sysreg_el1(v, spsr); > >+ case KVM_SPSR_ABT: > >+ write_sysreg(v, spsr_abt); > >+ case KVM_SPSR_UND: > >+ write_sysreg(v, spsr_und); > >+ case KVM_SPSR_IRQ: > >+ write_sysreg(v, spsr_irq); > >+ case KVM_SPSR_FIQ: > >+ write_sysreg(v, spsr_fiq); > >+ } > > }