Merge tag 'cris-for-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/jesper...
[cascardo/linux.git] / arch / arm64 / kvm / hyp / tlb.c
1 /*
2  * Copyright (C) 2015 - ARM Ltd
3  * Author: Marc Zyngier <marc.zyngier@arm.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include <asm/kvm_hyp.h>
19
20 void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
21 {
22         dsb(ishst);
23
24         /* Switch to requested VMID */
25         kvm = kern_hyp_va(kvm);
26         write_sysreg(kvm->arch.vttbr, vttbr_el2);
27         isb();
28
29         /*
30          * We could do so much better if we had the VA as well.
31          * Instead, we invalidate Stage-2 for this IPA, and the
32          * whole of Stage-1. Weep...
33          */
34         ipa >>= 12;
35         asm volatile("tlbi ipas2e1is, %0" : : "r" (ipa));
36
37         /*
38          * We have to ensure completion of the invalidation at Stage-2,
39          * since a table walk on another CPU could refill a TLB with a
40          * complete (S1 + S2) walk based on the old Stage-2 mapping if
41          * the Stage-1 invalidation happened first.
42          */
43         dsb(ish);
44         asm volatile("tlbi vmalle1is" : : );
45         dsb(ish);
46         isb();
47
48         write_sysreg(0, vttbr_el2);
49 }
50
51 void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
52 {
53         dsb(ishst);
54
55         /* Switch to requested VMID */
56         kvm = kern_hyp_va(kvm);
57         write_sysreg(kvm->arch.vttbr, vttbr_el2);
58         isb();
59
60         asm volatile("tlbi vmalls12e1is" : : );
61         dsb(ish);
62         isb();
63
64         write_sysreg(0, vttbr_el2);
65 }
66
67 void __hyp_text __kvm_flush_vm_context(void)
68 {
69         dsb(ishst);
70         asm volatile("tlbi alle1is      \n"
71                      "ic ialluis          ": : );
72         dsb(ish);
73 }