book3s_64_vio_hv.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * This program is free software; you can redistribute it and/or modify
  3. * it under the terms of the GNU General Public License, version 2, as
  4. * published by the Free Software Foundation.
  5. *
  6. * This program is distributed in the hope that it will be useful,
  7. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. * GNU General Public License for more details.
  10. *
  11. * You should have received a copy of the GNU General Public License
  12. * along with this program; if not, write to the Free Software
  13. * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  14. *
  15. * Copyright 2010 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
  16. * Copyright 2011 David Gibson, IBM Corporation <dwg@au1.ibm.com>
  17. */
  18. #include <linux/types.h>
  19. #include <linux/string.h>
  20. #include <linux/kvm.h>
  21. #include <linux/kvm_host.h>
  22. #include <linux/highmem.h>
  23. #include <linux/gfp.h>
  24. #include <linux/slab.h>
  25. #include <linux/hugetlb.h>
  26. #include <linux/list.h>
  27. #include <asm/tlbflush.h>
  28. #include <asm/kvm_ppc.h>
  29. #include <asm/kvm_book3s.h>
  30. #include <asm/mmu-hash64.h>
  31. #include <asm/hvcall.h>
  32. #include <asm/synch.h>
  33. #include <asm/ppc-opcode.h>
  34. #include <asm/kvm_host.h>
  35. #include <asm/udbg.h>
  36. #define TCES_PER_PAGE (PAGE_SIZE / sizeof(u64))
  37. /* WARNING: This will be called in real-mode on HV KVM and virtual
  38. * mode on PR KVM
  39. */
  40. long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
  41. unsigned long ioba, unsigned long tce)
  42. {
  43. struct kvm *kvm = vcpu->kvm;
  44. struct kvmppc_spapr_tce_table *stt;
  45. /* udbg_printf("H_PUT_TCE(): liobn=0x%lx ioba=0x%lx, tce=0x%lx\n", */
  46. /* liobn, ioba, tce); */
  47. list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) {
  48. if (stt->liobn == liobn) {
  49. unsigned long idx = ioba >> SPAPR_TCE_SHIFT;
  50. struct page *page;
  51. u64 *tbl;
  52. /* udbg_printf("H_PUT_TCE: liobn 0x%lx => stt=%p window_size=0x%x\n", */
  53. /* liobn, stt, stt->window_size); */
  54. if (ioba >= stt->window_size)
  55. return H_PARAMETER;
  56. page = stt->pages[idx / TCES_PER_PAGE];
  57. tbl = (u64 *)page_address(page);
  58. /* FIXME: Need to validate the TCE itself */
  59. /* udbg_printf("tce @ %p\n", &tbl[idx % TCES_PER_PAGE]); */
  60. tbl[idx % TCES_PER_PAGE] = tce;
  61. return H_SUCCESS;
  62. }
  63. }
  64. /* Didn't find the liobn, punt it to userspace */
  65. return H_TOO_HARD;
  66. }
  67. EXPORT_SYMBOL_GPL(kvmppc_h_put_tce);
  68. long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
  69. unsigned long ioba)
  70. {
  71. struct kvm *kvm = vcpu->kvm;
  72. struct kvmppc_spapr_tce_table *stt;
  73. list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) {
  74. if (stt->liobn == liobn) {
  75. unsigned long idx = ioba >> SPAPR_TCE_SHIFT;
  76. struct page *page;
  77. u64 *tbl;
  78. if (ioba >= stt->window_size)
  79. return H_PARAMETER;
  80. page = stt->pages[idx / TCES_PER_PAGE];
  81. tbl = (u64 *)page_address(page);
  82. vcpu->arch.gpr[4] = tbl[idx % TCES_PER_PAGE];
  83. return H_SUCCESS;
  84. }
  85. }
  86. /* Didn't find the liobn, punt it to userspace */
  87. return H_TOO_HARD;
  88. }
  89. EXPORT_SYMBOL_GPL(kvmppc_h_get_tce);