io-pgtable.c 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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. {
  27. #ifdef CONFIG_IOMMU_IO_PGTABLE_LPAE
  28. [ARM_32_LPAE_S1] = &io_pgtable_arm_32_lpae_s1_init_fns,
  29. [ARM_32_LPAE_S2] = &io_pgtable_arm_32_lpae_s2_init_fns,
  30. [ARM_64_LPAE_S1] = &io_pgtable_arm_64_lpae_s1_init_fns,
  31. [ARM_64_LPAE_S2] = &io_pgtable_arm_64_lpae_s2_init_fns,
  32. #endif
  33. };
  34. struct io_pgtable_ops *alloc_io_pgtable_ops(enum io_pgtable_fmt fmt,
  35. struct io_pgtable_cfg *cfg,
  36. void *cookie)
  37. {
  38. struct io_pgtable *iop;
  39. const struct io_pgtable_init_fns *fns;
  40. if (fmt >= IO_PGTABLE_NUM_FMTS)
  41. return NULL;
  42. fns = io_pgtable_init_table[fmt];
  43. if (!fns)
  44. return NULL;
  45. iop = fns->alloc(cfg, cookie);
  46. if (!iop)
  47. return NULL;
  48. iop->fmt = fmt;
  49. iop->cookie = cookie;
  50. iop->cfg = *cfg;
  51. return &iop->ops;
  52. }
  53. /*
  54. * It is the IOMMU driver's responsibility to ensure that the page table
  55. * is no longer accessible to the walker by this point.
  56. */
  57. void free_io_pgtable_ops(struct io_pgtable_ops *ops)
  58. {
  59. struct io_pgtable *iop;
  60. if (!ops)
  61. return;
  62. iop = container_of(ops, struct io_pgtable, ops);
  63. iop->cfg.tlb->tlb_flush_all(iop->cookie);
  64. io_pgtable_init_table[iop->fmt]->free(iop);
  65. }