For ARM host like Realview-PB-A8 the linux guest kernel generates alignment faults at boot time and crashes. To handle this situation without adding much overhead we emulate SCTLR & CPACR read/write and ignore operations SCTLR_A bit. With this patch in-place we can boot Linux on Realview-PB-A8 guest. Signed-off-by: Anup Patel <anup at brainfault.org> --- arch/arm/kvm/emulate.c | 42 ++++++++++++++++++++++++++++++++++++++++++ arch/arm/kvm/interrupts.S | 4 ++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/arch/arm/kvm/emulate.c b/arch/arm/kvm/emulate.c index e356d1c..8a69d49 100644 --- a/arch/arm/kvm/emulate.c +++ b/arch/arm/kvm/emulate.c @@ -223,6 +223,38 @@ static bool read_zero(struct kvm_vcpu *vcpu, return true; } +static bool write_sctlr(struct kvm_vcpu *vcpu, + const struct coproc_params *p, + unsigned long arg) +{ + vcpu->arch.cp15[c1_SCTLR] = *vcpu_reg(vcpu, p->Rt1) & ~0x00000002; + return true; +} + +static bool read_sctlr(struct kvm_vcpu *vcpu, + const struct coproc_params *p, + unsigned long arg) +{ + *vcpu_reg(vcpu, p->Rt1) = vcpu->arch.cp15[c1_SCTLR]; + return true; +} + +static bool write_cpacr(struct kvm_vcpu *vcpu, + const struct coproc_params *p, + unsigned long arg) +{ + vcpu->arch.cp15[c1_CPACR] = *vcpu_reg(vcpu, p->Rt1); + return true; +} + +static bool read_cpacr(struct kvm_vcpu *vcpu, + const struct coproc_params *p, + unsigned long arg) +{ + *vcpu_reg(vcpu, p->Rt1) = vcpu->arch.cp15[c1_CPACR]; + return true; +} + static bool read_l2ctlr(struct kvm_vcpu *vcpu, const struct coproc_params *p, unsigned long arg) @@ -278,6 +310,16 @@ struct coproc_emulate { static const struct coproc_emulate coproc_emulate[] = { /* + * SCTLR access: + */ + { CRn( 1), CRm( 0), Op1( 0), Op2( 0), is32, WRITE, write_sctlr}, + { CRn( 1), CRm( 0), Op1( 0), Op2( 0), is32, READ, read_sctlr}, + /* + * CPACR access: + */ + { CRn( 1), CRm( 0), Op1( 0), Op2( 2), is32, WRITE, write_cpacr}, + { CRn( 1), CRm( 0), Op1( 0), Op2( 2), is32, READ, read_cpacr}, + /* * L2CTLR access: * * Ignore writes completely. diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S index 0cf4965..942667a 100644 --- a/arch/arm/kvm/interrupts.S +++ b/arch/arm/kvm/interrupts.S @@ -240,9 +240,9 @@ ENTRY(__kvm_flush_vm_context) * (hardware reset value is 0) */ .macro set_hstr entry mrc p15, 4, r2, c1, c1, 3 - ldr r3, =0x9e00 + ldr r3, =0x9e02 .if \entry == 1 - orr r2, r2, r3 @ Trap CR{9,10,11,12,15} + orr r2, r2, r3 @ Trap CR{1,9,10,11,12,15} .else bic r2, r2, r3 @ Don't trap any CRx accesses .endif -- 1.7.0.4