aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Kamensky <victor.kamensky@linaro.org>2014-06-12 12:30:02 -0400
committerChristoffer Dall <christoffer.dall@linaro.org>2014-07-11 07:57:38 -0400
commit19b0e60a63f758a28329aa40f4270a6c98c2dcb7 (patch)
treee0daa0196fc1f1ad793340121e276ab75981df02
parent64054c25cf7e060cd6780744fefe7ed3990e4f21 (diff)
ARM: KVM: handle 64bit values passed to mrcc or from mcrr instructions in BE case
In some cases the mcrr and mrrc instructions in combination with the ldrd and strd instructions need to deal with 64bit value in memory. The ldrd and strd instructions already handle endianness within word (register) boundaries but to get effect of the whole 64bit value represented correctly, rr_lo_hi macro is introduced and is used to swap registers positions when the mcrr and mrrc instructions are used. That has the effect of swapping two words. Signed-off-by: Victor Kamensky <victor.kamensky@linaro.org> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> Acked-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
-rw-r--r--arch/arm/include/asm/kvm_asm.h18
-rw-r--r--arch/arm/kvm/init.S4
-rw-r--r--arch/arm/kvm/interrupts.S4
-rw-r--r--arch/arm/kvm/interrupts_head.S6
4 files changed, 25 insertions, 7 deletions
diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h
index 53b3c4a50d5c..3a67bec72d0c 100644
--- a/arch/arm/include/asm/kvm_asm.h
+++ b/arch/arm/include/asm/kvm_asm.h
@@ -61,6 +61,24 @@
61#define ARM_EXCEPTION_FIQ 6 61#define ARM_EXCEPTION_FIQ 6
62#define ARM_EXCEPTION_HVC 7 62#define ARM_EXCEPTION_HVC 7
63 63
64/*
65 * The rr_lo_hi macro swaps a pair of registers depending on
66 * current endianness. It is used in conjunction with ldrd and strd
67 * instructions that load/store a 64-bit value from/to memory to/from
68 * a pair of registers which are used with the mrrc and mcrr instructions.
69 * If used with the ldrd/strd instructions, the a1 parameter is the first
70 * source/destination register and the a2 parameter is the second
71 * source/destination register. Note that the ldrd/strd instructions
72 * already swap the bytes within the words correctly according to the
73 * endianness setting, but the order of the registers need to be effectively
74 * swapped when used with the mrrc/mcrr instructions.
75 */
76#ifdef CONFIG_CPU_ENDIAN_BE8
77#define rr_lo_hi(a1, a2) a2, a1
78#else
79#define rr_lo_hi(a1, a2) a1, a2
80#endif
81
64#ifndef __ASSEMBLY__ 82#ifndef __ASSEMBLY__
65struct kvm; 83struct kvm;
66struct kvm_vcpu; 84struct kvm_vcpu;
diff --git a/arch/arm/kvm/init.S b/arch/arm/kvm/init.S
index 1b9844d369cc..2cc14dfad049 100644
--- a/arch/arm/kvm/init.S
+++ b/arch/arm/kvm/init.S
@@ -71,7 +71,7 @@ __do_hyp_init:
71 bne phase2 @ Yes, second stage init 71 bne phase2 @ Yes, second stage init
72 72
73 @ Set the HTTBR to point to the hypervisor PGD pointer passed 73 @ Set the HTTBR to point to the hypervisor PGD pointer passed
74 mcrr p15, 4, r2, r3, c2 74 mcrr p15, 4, rr_lo_hi(r2, r3), c2
75 75
76 @ Set the HTCR and VTCR to the same shareability and cacheability 76 @ Set the HTCR and VTCR to the same shareability and cacheability
77 @ settings as the non-secure TTBCR and with T0SZ == 0. 77 @ settings as the non-secure TTBCR and with T0SZ == 0.
@@ -137,7 +137,7 @@ phase2:
137 mov pc, r0 137 mov pc, r0
138 138
139target: @ We're now in the trampoline code, switch page tables 139target: @ We're now in the trampoline code, switch page tables
140 mcrr p15, 4, r2, r3, c2 140 mcrr p15, 4, rr_lo_hi(r2, r3), c2
141 isb 141 isb
142 142
143 @ Invalidate the old TLBs 143 @ Invalidate the old TLBs
diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S
index 0d68d4073068..24d4e65806a7 100644
--- a/arch/arm/kvm/interrupts.S
+++ b/arch/arm/kvm/interrupts.S
@@ -52,7 +52,7 @@ ENTRY(__kvm_tlb_flush_vmid_ipa)
52 dsb ishst 52 dsb ishst
53 add r0, r0, #KVM_VTTBR 53 add r0, r0, #KVM_VTTBR
54 ldrd r2, r3, [r0] 54 ldrd r2, r3, [r0]
55 mcrr p15, 6, r2, r3, c2 @ Write VTTBR 55 mcrr p15, 6, rr_lo_hi(r2, r3), c2 @ Write VTTBR
56 isb 56 isb
57 mcr p15, 0, r0, c8, c3, 0 @ TLBIALLIS (rt ignored) 57 mcr p15, 0, r0, c8, c3, 0 @ TLBIALLIS (rt ignored)
58 dsb ish 58 dsb ish
@@ -135,7 +135,7 @@ ENTRY(__kvm_vcpu_run)
135 ldr r1, [vcpu, #VCPU_KVM] 135 ldr r1, [vcpu, #VCPU_KVM]
136 add r1, r1, #KVM_VTTBR 136 add r1, r1, #KVM_VTTBR
137 ldrd r2, r3, [r1] 137 ldrd r2, r3, [r1]
138 mcrr p15, 6, r2, r3, c2 @ Write VTTBR 138 mcrr p15, 6, rr_lo_hi(r2, r3), c2 @ Write VTTBR
139 139
140 @ We're all done, just restore the GPRs and go to the guest 140 @ We're all done, just restore the GPRs and go to the guest
141 restore_guest_regs 141 restore_guest_regs
diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
index 68d99c69639c..98c8c5b9a87f 100644
--- a/arch/arm/kvm/interrupts_head.S
+++ b/arch/arm/kvm/interrupts_head.S
@@ -520,7 +520,7 @@ ARM_BE8(rev r6, r6 )
520 mcr p15, 0, r2, c14, c3, 1 @ CNTV_CTL 520 mcr p15, 0, r2, c14, c3, 1 @ CNTV_CTL
521 isb 521 isb
522 522
523 mrrc p15, 3, r2, r3, c14 @ CNTV_CVAL 523 mrrc p15, 3, rr_lo_hi(r2, r3), c14 @ CNTV_CVAL
524 ldr r4, =VCPU_TIMER_CNTV_CVAL 524 ldr r4, =VCPU_TIMER_CNTV_CVAL
525 add r5, vcpu, r4 525 add r5, vcpu, r4
526 strd r2, r3, [r5] 526 strd r2, r3, [r5]
@@ -560,12 +560,12 @@ ARM_BE8(rev r6, r6 )
560 560
561 ldr r2, [r4, #KVM_TIMER_CNTVOFF] 561 ldr r2, [r4, #KVM_TIMER_CNTVOFF]
562 ldr r3, [r4, #(KVM_TIMER_CNTVOFF + 4)] 562 ldr r3, [r4, #(KVM_TIMER_CNTVOFF + 4)]
563 mcrr p15, 4, r2, r3, c14 @ CNTVOFF 563 mcrr p15, 4, rr_lo_hi(r2, r3), c14 @ CNTVOFF
564 564
565 ldr r4, =VCPU_TIMER_CNTV_CVAL 565 ldr r4, =VCPU_TIMER_CNTV_CVAL
566 add r5, vcpu, r4 566 add r5, vcpu, r4
567 ldrd r2, r3, [r5] 567 ldrd r2, r3, [r5]
568 mcrr p15, 3, r2, r3, c14 @ CNTV_CVAL 568 mcrr p15, 3, rr_lo_hi(r2, r3), c14 @ CNTV_CVAL
569 isb 569 isb
570 570
571 ldr r2, [vcpu, #VCPU_TIMER_CNTV_CTL] 571 ldr r2, [vcpu, #VCPU_TIMER_CNTV_CTL]