book3s_64_vio_hv.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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. long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
  38. unsigned long ioba, unsigned long tce)
  39. {
  40. struct kvm *kvm = vcpu->kvm;
  41. struct kvmppc_spapr_tce_table *stt;
  42. /* udbg_printf("H_PUT_TCE(): liobn=0x%lx ioba=0x%lx, tce=0x%lx\n", */
  43. /* liobn, ioba, tce); */
  44. list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) {
  45. if (stt->liobn == liobn) {
  46. unsigned long idx = ioba >> SPAPR_TCE_SHIFT;
  47. struct page *page;
  48. u64 *tbl;
  49. /* udbg_printf("H_PUT_TCE: liobn 0x%lx => stt=%p window_size=0x%x\n", */
  50. /* liobn, stt, stt->window_size); */
  51. if (ioba >= stt->window_size)
  52. return H_PARAMETER;
  53. page = stt->pages[idx / TCES_PER_PAGE];
  54. tbl = (u64 *)page_address(page);
  55. /* FIXME: Need to validate the TCE itself */
  56. /* udbg_printf("tce @ %p\n", &tbl[idx % TCES_PER_PAGE]); */
  57. tbl[idx % TCES_PER_PAGE] = tce;
  58. return H_SUCCESS;
  59. }
  60. }
  61. /* Didn't find the liobn, punt it to userspace */
  62. return H_TOO_HARD;
  63. }