grant-table.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /******************************************************************************
  2. * grant_table.c
  3. * x86 specific part
  4. *
  5. * Granting foreign access to our memory reservation.
  6. *
  7. * Copyright (c) 2005-2006, Christopher Clark
  8. * Copyright (c) 2004-2005, K A Fraser
  9. * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
  10. * VA Linux Systems Japan. Split out x86 specific part.
  11. *
  12. * This program is free software; you can redistribute it and/or
  13. * modify it under the terms of the GNU General Public License version 2
  14. * as published by the Free Software Foundation; or, when distributed
  15. * separately from the Linux kernel or incorporated into other
  16. * software packages, subject to the following license:
  17. *
  18. * Permission is hereby granted, free of charge, to any person obtaining a copy
  19. * of this source file (the "Software"), to deal in the Software without
  20. * restriction, including without limitation the rights to use, copy, modify,
  21. * merge, publish, distribute, sublicense, and/or sell copies of the Software,
  22. * and to permit persons to whom the Software is furnished to do so, subject to
  23. * the following conditions:
  24. *
  25. * The above copyright notice and this permission notice shall be included in
  26. * all copies or substantial portions of the Software.
  27. *
  28. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  29. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  30. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  31. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  32. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  33. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  34. * IN THE SOFTWARE.
  35. */
  36. #include <linux/sched.h>
  37. #include <linux/mm.h>
  38. #include <linux/vmalloc.h>
  39. #include <xen/interface/xen.h>
  40. #include <xen/page.h>
  41. #include <xen/grant_table.h>
  42. #include <asm/pgtable.h>
  43. static int map_pte_fn(pte_t *pte, struct page *pmd_page,
  44. unsigned long addr, void *data)
  45. {
  46. unsigned long **frames = (unsigned long **)data;
  47. set_pte_at(&init_mm, addr, pte, mfn_pte((*frames)[0], PAGE_KERNEL));
  48. (*frames)++;
  49. return 0;
  50. }
  51. /*
  52. * This function is used to map shared frames to store grant status. It is
  53. * different from map_pte_fn above, the frames type here is uint64_t.
  54. */
  55. static int map_pte_fn_status(pte_t *pte, struct page *pmd_page,
  56. unsigned long addr, void *data)
  57. {
  58. uint64_t **frames = (uint64_t **)data;
  59. set_pte_at(&init_mm, addr, pte, mfn_pte((*frames)[0], PAGE_KERNEL));
  60. (*frames)++;
  61. return 0;
  62. }
  63. static int unmap_pte_fn(pte_t *pte, struct page *pmd_page,
  64. unsigned long addr, void *data)
  65. {
  66. set_pte_at(&init_mm, addr, pte, __pte(0));
  67. return 0;
  68. }
  69. int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
  70. unsigned long max_nr_gframes,
  71. void **__shared)
  72. {
  73. int rc;
  74. void *shared = *__shared;
  75. if (shared == NULL) {
  76. struct vm_struct *area =
  77. alloc_vm_area(PAGE_SIZE * max_nr_gframes, NULL);
  78. BUG_ON(area == NULL);
  79. shared = area->addr;
  80. *__shared = shared;
  81. }
  82. rc = apply_to_page_range(&init_mm, (unsigned long)shared,
  83. PAGE_SIZE * nr_gframes,
  84. map_pte_fn, &frames);
  85. return rc;
  86. }
  87. int arch_gnttab_map_status(uint64_t *frames, unsigned long nr_gframes,
  88. unsigned long max_nr_gframes,
  89. grant_status_t **__shared)
  90. {
  91. int rc;
  92. grant_status_t *shared = *__shared;
  93. if (shared == NULL) {
  94. /* No need to pass in PTE as we are going to do it
  95. * in apply_to_page_range anyhow. */
  96. struct vm_struct *area =
  97. alloc_vm_area(PAGE_SIZE * max_nr_gframes, NULL);
  98. BUG_ON(area == NULL);
  99. shared = area->addr;
  100. *__shared = shared;
  101. }
  102. rc = apply_to_page_range(&init_mm, (unsigned long)shared,
  103. PAGE_SIZE * nr_gframes,
  104. map_pte_fn_status, &frames);
  105. return rc;
  106. }
  107. void arch_gnttab_unmap(void *shared, unsigned long nr_gframes)
  108. {
  109. apply_to_page_range(&init_mm, (unsigned long)shared,
  110. PAGE_SIZE * nr_gframes, unmap_pte_fn, NULL);
  111. }