There is strictly no reason to have two fields to describe the faulting VA - we only get one fault at a time, and the 64bit architecture unifies it for that very reason. We have to rely on HSR to find out how to interpret the data anyway. Squash the two fields into one, and perform the associated cleanup. Signed-off-by: Marc Zyngier <marc.zyngier@xxxxxxx> --- arch/arm/include/asm/kvm_host.h | 3 +-- arch/arm/kernel/asm-offsets.c | 3 +-- arch/arm/kvm/arm.c | 4 ++-- arch/arm/kvm/emulate.c | 6 +++--- arch/arm/kvm/interrupts.S | 9 ++++----- arch/arm/kvm/mmu.c | 12 ++++++------ arch/arm/kvm/trace.h | 14 ++++++-------- 7 files changed, 23 insertions(+), 28 deletions(-) diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h index 25ab5be..eb483b3 100644 --- a/arch/arm/include/asm/kvm_host.h +++ b/arch/arm/include/asm/kvm_host.h @@ -88,8 +88,7 @@ struct kvm_vcpu_arch { /* Exception Information */ u32 hsr; /* Hyp Syndrom Register */ - u32 hdfar; /* Hyp Data Fault Address Register */ - u32 hifar; /* Hyp Inst. Fault Address Register */ + u32 hxfar; /* Hyp Data/Inst Fault Address Register */ u32 hpfar; /* Hyp IPA Fault Address Register */ /* Floating point registers (VFP and Advanced SIMD/NEON) */ diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index ff3f43b..cc5e6af 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -162,8 +162,7 @@ int main(void) DEFINE(VCPU_CPSR, offsetof(struct kvm_vcpu, arch.regs.usr_regs.ARM_cpsr)); DEFINE(VCPU_IRQ_LINES, offsetof(struct kvm_vcpu, arch.irq_lines)); DEFINE(VCPU_HSR, offsetof(struct kvm_vcpu, arch.hsr)); - DEFINE(VCPU_HDFAR, offsetof(struct kvm_vcpu, arch.hdfar)); - DEFINE(VCPU_HIFAR, offsetof(struct kvm_vcpu, arch.hifar)); + DEFINE(VCPU_HxFAR, offsetof(struct kvm_vcpu, arch.hxfar)); DEFINE(VCPU_HPFAR, offsetof(struct kvm_vcpu, arch.hpfar)); DEFINE(VCPU_HYP_PC, offsetof(struct kvm_vcpu, arch.hyp_pc)); #ifdef CONFIG_KVM_ARM_VGIC diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 491ac38..ab01865 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -489,7 +489,7 @@ static int handle_pabt_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run) { /* The hypervisor should never cause aborts */ kvm_err("Prefetch Abort taken from Hyp mode at %#08x (HSR: %#08x)\n", - vcpu->arch.hifar, vcpu->arch.hsr); + vcpu->arch.hxfar, vcpu->arch.hsr); return -EFAULT; } @@ -497,7 +497,7 @@ static int handle_dabt_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run) { /* This is either an error in the ws. code or an external abort */ kvm_err("Data Abort taken from Hyp mode at %#08x (HSR: %#08x)\n", - vcpu->arch.hdfar, vcpu->arch.hsr); + vcpu->arch.hxfar, vcpu->arch.hsr); return -EFAULT; } diff --git a/arch/arm/kvm/emulate.c b/arch/arm/kvm/emulate.c index bac59c7..f12a1c8 100644 --- a/arch/arm/kvm/emulate.c +++ b/arch/arm/kvm/emulate.c @@ -476,7 +476,7 @@ static bool decode_thumb_wb(struct kvm_vcpu *vcpu, struct kvm_exit_mmio *mmio, bool P = (instr >> 10) & 1; bool U = (instr >> 9) & 1; u8 imm8 = instr & 0xff; - u32 offset_addr = vcpu->arch.hdfar; + u32 offset_addr = vcpu->arch.hxfar; u8 Rn = (instr >> 16) & 0xf; vcpu->arch.mmio.rd = (instr >> 12) & 0xf; @@ -632,13 +632,13 @@ int kvm_emulate_mmio_ls(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, kvm_debug("Unable to decode inst: %#08lx (cpsr: %#08x (T=0)" "pc: %#08x)\n", instr, *vcpu_cpsr(vcpu), *vcpu_pc(vcpu)); - kvm_inject_dabt(vcpu, vcpu->arch.hdfar); + kvm_inject_dabt(vcpu, vcpu->arch.hxfar); return 1; } else if (is_thumb && !kvm_decode_thumb_ls(vcpu, instr, mmio)) { kvm_debug("Unable to decode inst: %#08lx (cpsr: %#08x (T=1)" "pc: %#08x)\n", instr, *vcpu_cpsr(vcpu), *vcpu_pc(vcpu)); - kvm_inject_dabt(vcpu, vcpu->arch.hdfar); + kvm_inject_dabt(vcpu, vcpu->arch.hxfar); return 1; } diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S index ee097f8..18c5952 100644 --- a/arch/arm/kvm/interrupts.S +++ b/arch/arm/kvm/interrupts.S @@ -276,13 +276,13 @@ ENTRY(kvm_call_hyp) mrc p15, 4, r2, c5, c2, 0 @ HSR mrc p15, 4, r0, c6, c0, 0 @ HDFAR str r2, [r1, #VCPU_HSR] - str r0, [r1, #VCPU_HDFAR] + str r0, [r1, #VCPU_HxFAR] .endif .if \exception_code == ARM_EXCEPTION_PREF_ABORT mrc p15, 4, r2, c5, c2, 0 @ HSR mrc p15, 4, r0, c6, c0, 2 @ HIFAR str r2, [r1, #VCPU_HSR] - str r0, [r1, #VCPU_HIFAR] + str r0, [r1, #VCPU_HxFAR] .endif mov r0, #\exception_code b __kvm_vcpu_return @@ -393,14 +393,13 @@ guest_trap: lsr r0, r0, #HSR_EC_SHIFT cmp r0, #HSR_EC_IABT mrceq p15, 4, r2, c6, c0, 2 @ HIFAR - streq r2, [r1, #VCPU_HIFAR] beq 2f cmp r0, #HSR_EC_DABT bne 1f mrc p15, 4, r2, c6, c0, 0 @ HDFAR - str r2, [r1, #VCPU_HDFAR] -2: mrc p15, 4, r2, c6, c0, 4 @ HPFAR +2: str r2, [r1, #VCPU_HxFAR] + mrc p15, 4, r2, c6, c0, 4 @ HPFAR str r2, [r1, #VCPU_HPFAR] 1: mov r0, #ARM_EXCEPTION_HVC diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index f955995..fc6833e 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -761,13 +761,13 @@ static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, if ((vcpu->arch.hsr >> 8) & 1) { /* cache operation on I/O addr, tell guest unsupported */ - kvm_inject_dabt(vcpu, vcpu->arch.hdfar); + kvm_inject_dabt(vcpu, vcpu->arch.hxfar); return 1; } if ((vcpu->arch.hsr >> 7) & 1) { /* page table accesses IO mem: tell guest to fix its TTBR */ - kvm_inject_dabt(vcpu, vcpu->arch.hdfar); + kvm_inject_dabt(vcpu, vcpu->arch.hxfar); return 1; } @@ -792,7 +792,7 @@ static int decode_hsr(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, if (rd == 15) { /* IO memory trying to read/write pc */ - kvm_inject_pabt(vcpu, vcpu->arch.hdfar); + kvm_inject_pabt(vcpu, vcpu->arch.hxfar); return 1; } @@ -875,7 +875,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) fault_ipa = ((phys_addr_t)vcpu->arch.hpfar & HPFAR_MASK) << 8; trace_kvm_guest_fault(*vcpu_pc(vcpu), vcpu->arch.hsr, - vcpu->arch.hdfar, vcpu->arch.hifar, fault_ipa); + vcpu->arch.hxfar, fault_ipa); /* Check the stage-2 fault is trans. fault or write fault */ fault_status = (vcpu->arch.hsr & HSR_FSC_TYPE); @@ -889,7 +889,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) if (!kvm_is_visible_gfn(vcpu->kvm, gfn)) { if (is_iabt) { /* Prefetch Abort on I/O address */ - kvm_inject_pabt(vcpu, vcpu->arch.hifar); + kvm_inject_pabt(vcpu, vcpu->arch.hxfar); return 1; } @@ -900,7 +900,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) } /* Adjust page offset */ - fault_ipa |= vcpu->arch.hdfar & ~PAGE_MASK; + fault_ipa |= vcpu->arch.hxfar & ~PAGE_MASK; return io_mem_abort(vcpu, run, fault_ipa, memslot); } diff --git a/arch/arm/kvm/trace.h b/arch/arm/kvm/trace.h index 67a2598..c3d05f4 100644 --- a/arch/arm/kvm/trace.h +++ b/arch/arm/kvm/trace.h @@ -41,29 +41,27 @@ TRACE_EVENT(kvm_exit, TRACE_EVENT(kvm_guest_fault, TP_PROTO(unsigned long vcpu_pc, unsigned long hsr, - unsigned long hdfar, unsigned long hifar, + unsigned long hxfar, unsigned long ipa), - TP_ARGS(vcpu_pc, hsr, hdfar, hifar, ipa), + TP_ARGS(vcpu_pc, hsr, hxfar, ipa), TP_STRUCT__entry( __field( unsigned long, vcpu_pc ) __field( unsigned long, hsr ) - __field( unsigned long, hdfar ) - __field( unsigned long, hifar ) + __field( unsigned long, hxfar ) __field( unsigned long, ipa ) ), TP_fast_assign( __entry->vcpu_pc = vcpu_pc; __entry->hsr = hsr; - __entry->hdfar = hdfar; - __entry->hifar = hifar; + __entry->hxfar = hxfar; __entry->ipa = ipa; ), - TP_printk("guest fault at PC %#08lx (hdfar %#08lx, hifar %#08lx, " + TP_printk("guest fault at PC %#08lx (hxfar %#08lx, " "ipa %#08lx, hsr %#08lx", - __entry->vcpu_pc, __entry->hdfar, __entry->hifar, + __entry->vcpu_pc, __entry->hxfar, __entry->hsr, __entry->ipa) ); -- 1.7.12 _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm