1/* 2 * Original code: 3 * Copyright (C) 2012 - Virtual Open Systems and Columbia University 4 * Author: Christoffer Dall <c.dall@virtualopensystems.com> 5 * 6 * Mostly rewritten in C by Marc Zyngier <marc.zyngier@arm.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21#include <asm/kvm_hyp.h> 22 23/** 24 * Flush per-VMID TLBs 25 * 26 * __kvm_tlb_flush_vmid(struct kvm *kvm); 27 * 28 * We rely on the hardware to broadcast the TLB invalidation to all CPUs 29 * inside the inner-shareable domain (which is the case for all v7 30 * implementations). If we come across a non-IS SMP implementation, we'll 31 * have to use an IPI based mechanism. Until then, we stick to the simple 32 * hardware assisted version. 33 * 34 * As v7 does not support flushing per IPA, just nuke the whole TLB 35 * instead, ignoring the ipa value. 36 */ 37void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm) 38{ 39 dsb(ishst); 40 41 /* Switch to requested VMID */ 42 kvm = kern_hyp_va(kvm); 43 write_sysreg(kvm->arch.vttbr, VTTBR); 44 isb(); 45 46 write_sysreg(0, TLBIALLIS); 47 dsb(ish); 48 isb(); 49 50 write_sysreg(0, VTTBR); 51} 52 53void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa) 54{ 55 __kvm_tlb_flush_vmid(kvm); 56} 57 58void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu) 59{ 60 struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm); 61 62 /* Switch to requested VMID */ 63 write_sysreg(kvm->arch.vttbr, VTTBR); 64 isb(); 65 66 write_sysreg(0, TLBIALL); 67 dsb(nsh); 68 isb(); 69 70 write_sysreg(0, VTTBR); 71} 72 73void __hyp_text __kvm_flush_vm_context(void) 74{ 75 write_sysreg(0, TLBIALLNSNHIS); 76 write_sysreg(0, ICIALLUIS); 77 dsb(ish); 78} 79