tlb.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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. #include <asm/kvm_hyp.h>
  18. void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
  19. {
  20. dsb(ishst);
  21. /* Switch to requested VMID */
  22. kvm = kern_hyp_va(kvm);
  23. write_sysreg(kvm->arch.vttbr, vttbr_el2);
  24. isb();
  25. /*
  26. * We could do so much better if we had the VA as well.
  27. * Instead, we invalidate Stage-2 for this IPA, and the
  28. * whole of Stage-1. Weep...
  29. */
  30. ipa >>= 12;
  31. asm volatile("tlbi ipas2e1is, %0" : : "r" (ipa));
  32. /*
  33. * We have to ensure completion of the invalidation at Stage-2,
  34. * since a table walk on another CPU could refill a TLB with a
  35. * complete (S1 + S2) walk based on the old Stage-2 mapping if
  36. * the Stage-1 invalidation happened first.
  37. */
  38. dsb(ish);
  39. asm volatile("tlbi vmalle1is" : : );
  40. dsb(ish);
  41. isb();
  42. write_sysreg(0, vttbr_el2);
  43. }
  44. void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
  45. {
  46. dsb(ishst);
  47. /* Switch to requested VMID */
  48. kvm = kern_hyp_va(kvm);
  49. write_sysreg(kvm->arch.vttbr, vttbr_el2);
  50. isb();
  51. asm volatile("tlbi vmalls12e1is" : : );
  52. dsb(ish);
  53. isb();
  54. write_sysreg(0, vttbr_el2);
  55. }
  56. void __hyp_text __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu)
  57. {
  58. struct kvm *kvm = kern_hyp_va(kern_hyp_va(vcpu)->kvm);
  59. /* Switch to requested VMID */
  60. write_sysreg(kvm->arch.vttbr, vttbr_el2);
  61. isb();
  62. asm volatile("tlbi vmalle1" : : );
  63. dsb(nsh);
  64. isb();
  65. write_sysreg(0, vttbr_el2);
  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. }