diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2014-01-22 05:20:09 -0500 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2014-03-02 20:15:24 -0500 |
commit | af20814ee927ed888288d98917a766b4179c4fe0 (patch) | |
tree | d8b2dea94adc055c7a9fc351b94a72960ccc0cc9 /arch | |
parent | ac30a11e8e92a03dbe236b285c5cbae0bf563141 (diff) |
ARM: KVM: add world-switch for AMAIR{0,1}
HCR.TVM traps (among other things) accesses to AMAIR0 and AMAIR1.
In order to minimise the amount of surprise a guest could generate by
trying to access these registers with caches off, add them to the
list of registers we switch/handle.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/include/asm/kvm_asm.h | 4 | ||||
-rw-r--r-- | arch/arm/kvm/coproc.c | 6 | ||||
-rw-r--r-- | arch/arm/kvm/interrupts_head.S | 12 |
3 files changed, 19 insertions, 3 deletions
diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h index 661da11f76f4..53b3c4a50d5c 100644 --- a/arch/arm/include/asm/kvm_asm.h +++ b/arch/arm/include/asm/kvm_asm.h | |||
@@ -48,7 +48,9 @@ | |||
48 | #define c13_TID_URO 26 /* Thread ID, User R/O */ | 48 | #define c13_TID_URO 26 /* Thread ID, User R/O */ |
49 | #define c13_TID_PRIV 27 /* Thread ID, Privileged */ | 49 | #define c13_TID_PRIV 27 /* Thread ID, Privileged */ |
50 | #define c14_CNTKCTL 28 /* Timer Control Register (PL1) */ | 50 | #define c14_CNTKCTL 28 /* Timer Control Register (PL1) */ |
51 | #define NR_CP15_REGS 29 /* Number of regs (incl. invalid) */ | 51 | #define c10_AMAIR0 29 /* Auxilary Memory Attribute Indirection Reg0 */ |
52 | #define c10_AMAIR1 30 /* Auxilary Memory Attribute Indirection Reg1 */ | ||
53 | #define NR_CP15_REGS 31 /* Number of regs (incl. invalid) */ | ||
52 | 54 | ||
53 | #define ARM_EXCEPTION_RESET 0 | 55 | #define ARM_EXCEPTION_RESET 0 |
54 | #define ARM_EXCEPTION_UNDEFINED 1 | 56 | #define ARM_EXCEPTION_UNDEFINED 1 |
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c index 126c90d18387..a5a54a48d51b 100644 --- a/arch/arm/kvm/coproc.c +++ b/arch/arm/kvm/coproc.c | |||
@@ -328,6 +328,12 @@ static const struct coproc_reg cp15_regs[] = { | |||
328 | { CRn(10), CRm( 2), Op1( 0), Op2( 1), is32, | 328 | { CRn(10), CRm( 2), Op1( 0), Op2( 1), is32, |
329 | NULL, reset_unknown, c10_NMRR}, | 329 | NULL, reset_unknown, c10_NMRR}, |
330 | 330 | ||
331 | /* AMAIR0/AMAIR1: swapped by interrupt.S. */ | ||
332 | { CRn(10), CRm( 3), Op1( 0), Op2( 0), is32, | ||
333 | access_vm_reg, reset_unknown, c10_AMAIR0}, | ||
334 | { CRn(10), CRm( 3), Op1( 0), Op2( 1), is32, | ||
335 | access_vm_reg, reset_unknown, c10_AMAIR1}, | ||
336 | |||
331 | /* VBAR: swapped by interrupt.S. */ | 337 | /* VBAR: swapped by interrupt.S. */ |
332 | { CRn(12), CRm( 0), Op1( 0), Op2( 0), is32, | 338 | { CRn(12), CRm( 0), Op1( 0), Op2( 0), is32, |
333 | NULL, reset_val, c12_VBAR, 0x00000000 }, | 339 | NULL, reset_val, c12_VBAR, 0x00000000 }, |
diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S index a37270d7d4d6..76af93025574 100644 --- a/arch/arm/kvm/interrupts_head.S +++ b/arch/arm/kvm/interrupts_head.S | |||
@@ -303,13 +303,17 @@ vcpu .req r0 @ vcpu pointer always in r0 | |||
303 | 303 | ||
304 | mrc p15, 0, r2, c14, c1, 0 @ CNTKCTL | 304 | mrc p15, 0, r2, c14, c1, 0 @ CNTKCTL |
305 | mrrc p15, 0, r4, r5, c7 @ PAR | 305 | mrrc p15, 0, r4, r5, c7 @ PAR |
306 | mrc p15, 0, r6, c10, c3, 0 @ AMAIR0 | ||
307 | mrc p15, 0, r7, c10, c3, 1 @ AMAIR1 | ||
306 | 308 | ||
307 | .if \store_to_vcpu == 0 | 309 | .if \store_to_vcpu == 0 |
308 | push {r2,r4-r5} | 310 | push {r2,r4-r7} |
309 | .else | 311 | .else |
310 | str r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)] | 312 | str r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)] |
311 | add r12, vcpu, #CP15_OFFSET(c7_PAR) | 313 | add r12, vcpu, #CP15_OFFSET(c7_PAR) |
312 | strd r4, r5, [r12] | 314 | strd r4, r5, [r12] |
315 | str r6, [vcpu, #CP15_OFFSET(c10_AMAIR0)] | ||
316 | str r7, [vcpu, #CP15_OFFSET(c10_AMAIR1)] | ||
313 | .endif | 317 | .endif |
314 | .endm | 318 | .endm |
315 | 319 | ||
@@ -322,15 +326,19 @@ vcpu .req r0 @ vcpu pointer always in r0 | |||
322 | */ | 326 | */ |
323 | .macro write_cp15_state read_from_vcpu | 327 | .macro write_cp15_state read_from_vcpu |
324 | .if \read_from_vcpu == 0 | 328 | .if \read_from_vcpu == 0 |
325 | pop {r2,r4-r5} | 329 | pop {r2,r4-r7} |
326 | .else | 330 | .else |
327 | ldr r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)] | 331 | ldr r2, [vcpu, #CP15_OFFSET(c14_CNTKCTL)] |
328 | add r12, vcpu, #CP15_OFFSET(c7_PAR) | 332 | add r12, vcpu, #CP15_OFFSET(c7_PAR) |
329 | ldrd r4, r5, [r12] | 333 | ldrd r4, r5, [r12] |
334 | ldr r6, [vcpu, #CP15_OFFSET(c10_AMAIR0)] | ||
335 | ldr r7, [vcpu, #CP15_OFFSET(c10_AMAIR1)] | ||
330 | .endif | 336 | .endif |
331 | 337 | ||
332 | mcr p15, 0, r2, c14, c1, 0 @ CNTKCTL | 338 | mcr p15, 0, r2, c14, c1, 0 @ CNTKCTL |
333 | mcrr p15, 0, r4, r5, c7 @ PAR | 339 | mcrr p15, 0, r4, r5, c7 @ PAR |
340 | mcr p15, 0, r6, c10, c3, 0 @ AMAIR0 | ||
341 | mcr p15, 0, r7, c10, c3, 1 @ AMAIR1 | ||
334 | 342 | ||
335 | .if \read_from_vcpu == 0 | 343 | .if \read_from_vcpu == 0 |
336 | pop {r2-r12} | 344 | pop {r2-r12} |