forked from Minki/linux
f6edbbf36d
X-Gene u-boot runs in EL2 mode with MMU enabled hence we might have stale EL2 tlb enteris when we enable EL2 MMU on each host CPU. This can happen on any ARM/ARM64 board running bootloader in Hyp-mode (or EL2-mode) with MMU enabled. This patch ensures that we flush all Hyp-mode (or EL2-mode) TLBs on each host CPU before enabling Hyp-mode (or EL2-mode) MMU. Cc: <stable@vger.kernel.org> Tested-by: Mark Rutland <mark.rutland@arm.com> Reviewed-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Pranavkumar Sawargaonkar <pranavkumar@linaro.org> Signed-off-by: Anup Patel <anup.patel@linaro.org> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
121 lines
2.5 KiB
ArmAsm
121 lines
2.5 KiB
ArmAsm
/*
|
|
* Copyright (C) 2012,2013 - ARM Ltd
|
|
* Author: Marc Zyngier <marc.zyngier@arm.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License, version 2, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <linux/linkage.h>
|
|
|
|
#include <asm/assembler.h>
|
|
#include <asm/kvm_arm.h>
|
|
#include <asm/kvm_mmu.h>
|
|
|
|
.text
|
|
.pushsection .hyp.idmap.text, "ax"
|
|
|
|
.align 11
|
|
|
|
ENTRY(__kvm_hyp_init)
|
|
ventry __invalid // Synchronous EL2t
|
|
ventry __invalid // IRQ EL2t
|
|
ventry __invalid // FIQ EL2t
|
|
ventry __invalid // Error EL2t
|
|
|
|
ventry __invalid // Synchronous EL2h
|
|
ventry __invalid // IRQ EL2h
|
|
ventry __invalid // FIQ EL2h
|
|
ventry __invalid // Error EL2h
|
|
|
|
ventry __do_hyp_init // Synchronous 64-bit EL1
|
|
ventry __invalid // IRQ 64-bit EL1
|
|
ventry __invalid // FIQ 64-bit EL1
|
|
ventry __invalid // Error 64-bit EL1
|
|
|
|
ventry __invalid // Synchronous 32-bit EL1
|
|
ventry __invalid // IRQ 32-bit EL1
|
|
ventry __invalid // FIQ 32-bit EL1
|
|
ventry __invalid // Error 32-bit EL1
|
|
|
|
__invalid:
|
|
b .
|
|
|
|
/*
|
|
* x0: HYP boot pgd
|
|
* x1: HYP pgd
|
|
* x2: HYP stack
|
|
* x3: HYP vectors
|
|
*/
|
|
__do_hyp_init:
|
|
|
|
msr ttbr0_el2, x0
|
|
|
|
mrs x4, tcr_el1
|
|
ldr x5, =TCR_EL2_MASK
|
|
and x4, x4, x5
|
|
ldr x5, =TCR_EL2_FLAGS
|
|
orr x4, x4, x5
|
|
msr tcr_el2, x4
|
|
|
|
ldr x4, =VTCR_EL2_FLAGS
|
|
/*
|
|
* Read the PARange bits from ID_AA64MMFR0_EL1 and set the PS bits in
|
|
* VTCR_EL2.
|
|
*/
|
|
mrs x5, ID_AA64MMFR0_EL1
|
|
bfi x4, x5, #16, #3
|
|
msr vtcr_el2, x4
|
|
|
|
mrs x4, mair_el1
|
|
msr mair_el2, x4
|
|
isb
|
|
|
|
/* Invalidate the stale TLBs from Bootloader */
|
|
tlbi alle2
|
|
dsb sy
|
|
|
|
mrs x4, sctlr_el2
|
|
and x4, x4, #SCTLR_EL2_EE // preserve endianness of EL2
|
|
ldr x5, =SCTLR_EL2_FLAGS
|
|
orr x4, x4, x5
|
|
msr sctlr_el2, x4
|
|
isb
|
|
|
|
/* MMU is now enabled. Get ready for the trampoline dance */
|
|
ldr x4, =TRAMPOLINE_VA
|
|
adr x5, target
|
|
bfi x4, x5, #0, #PAGE_SHIFT
|
|
br x4
|
|
|
|
target: /* We're now in the trampoline code, switch page tables */
|
|
msr ttbr0_el2, x1
|
|
isb
|
|
|
|
/* Invalidate the old TLBs */
|
|
tlbi alle2
|
|
dsb sy
|
|
|
|
/* Set the stack and new vectors */
|
|
kern_hyp_va x2
|
|
mov sp, x2
|
|
kern_hyp_va x3
|
|
msr vbar_el2, x3
|
|
|
|
/* Hello, World! */
|
|
eret
|
|
ENDPROC(__kvm_hyp_init)
|
|
|
|
.ltorg
|
|
|
|
.popsection
|