io-pgtable.c 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /*
  2. * Generic page table allocator for IOMMUs.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. * Copyright (C) 2014 ARM Limited
  17. *
  18. * Author: Will Deacon <will.deacon@arm.com>
  19. */
  20. #include <linux/bug.h>
  21. #include <linux/kernel.h>
  22. #include <linux/types.h>
  23. #include "io-pgtable.h"
  24. static const struct io_pgtable_init_fns *
  25. io_pgtable_init_table[IO_PGTABLE_NUM_FMTS] = {
  26. #ifdef CONFIG_IOMMU_IO_PGTABLE_LPAE
  27. [ARM_32_LPAE_S1] = &io_pgtable_arm_32_lpae_s1_init_fns,
  28. [ARM_32_LPAE_S2] = &io_pgtable_arm_32_lpae_s2_init_fns,
  29. [ARM_64_LPAE_S1] = &io_pgtable_arm_64_lpae_s1_init_fns,
  30. [ARM_64_LPAE_S2] = &io_pgtable_arm_64_lpae_s2_init_fns,
  31. #endif
  32. #ifdef CONFIG_IOMMU_IO_PGTABLE_ARMV7S
  33. [ARM_V7S] = &io_pgtable_arm_v7s_init_fns,
  34. #endif
  35. };
  36. struct io_pgtable_ops *alloc_io_pgtable_ops(enum io_pgtable_fmt fmt,
  37. struct io_pgtable_cfg *cfg,
  38. void *cookie)
  39. {
  40. struct io_pgtable *iop;
  41. const struct io_pgtable_init_fns *fns;
  42. if (fmt >= IO_PGTABLE_NUM_FMTS)
  43. return NULL;
  44. fns = io_pgtable_init_table[fmt];
  45. if (!fns)
  46. return NULL;
  47. iop = fns->alloc(cfg, cookie);
  48. if (!iop)
  49. return NULL;
  50. iop->fmt = fmt;
  51. iop->cookie = cookie;
  52. iop->cfg = *cfg;
  53. return &iop->ops;
  54. }
  55. /*
  56. * It is the IOMMU driver's responsibility to ensure that the page table
  57. * is no longer accessible to the walker by this point.
  58. */
  59. void free_io_pgtable_ops(struct io_pgtable_ops *ops)
  60. {
  61. struct io_pgtable *iop;
  62. if (!ops)
  63. return;
  64. iop = container_of(ops, struct io_pgtable, ops);
  65. io_pgtable_tlb_flush_all(iop);
  66. io_pgtable_init_table[iop->fmt]->free(iop);
  67. }