linux/arch/x86/xen/grant-table.c
<<
>>
Prefs
   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
  37#include <linux/sched.h>
  38#include <linux/mm.h>
  39#include <linux/vmalloc.h>
  40
  41#include <xen/interface/xen.h>
  42#include <xen/page.h>
  43#include <xen/grant_table.h>
  44
  45#include <asm/pgtable.h>
  46
  47static int map_pte_fn(pte_t *pte, struct page *pmd_page,
  48                      unsigned long addr, void *data)
  49{
  50        unsigned long **frames = (unsigned long **)data;
  51
  52        set_pte_at(&init_mm, addr, pte, mfn_pte((*frames)[0], PAGE_KERNEL));
  53        (*frames)++;
  54        return 0;
  55}
  56
  57/*
  58 * This function is used to map shared frames to store grant status. It is
  59 * different from map_pte_fn above, the frames type here is uint64_t.
  60 */
  61static int map_pte_fn_status(pte_t *pte, struct page *pmd_page,
  62                             unsigned long addr, void *data)
  63{
  64        uint64_t **frames = (uint64_t **)data;
  65
  66        set_pte_at(&init_mm, addr, pte, mfn_pte((*frames)[0], PAGE_KERNEL));
  67        (*frames)++;
  68        return 0;
  69}
  70
  71static int unmap_pte_fn(pte_t *pte, struct page *pmd_page,
  72                        unsigned long addr, void *data)
  73{
  74
  75        set_pte_at(&init_mm, addr, pte, __pte(0));
  76        return 0;
  77}
  78
  79int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
  80                           unsigned long max_nr_gframes,
  81                           void **__shared)
  82{
  83        int rc;
  84        void *shared = *__shared;
  85
  86        if (shared == NULL) {
  87                struct vm_struct *area =
  88                        alloc_vm_area(PAGE_SIZE * max_nr_gframes, NULL);
  89                BUG_ON(area == NULL);
  90                shared = area->addr;
  91                *__shared = shared;
  92        }
  93
  94        rc = apply_to_page_range(&init_mm, (unsigned long)shared,
  95                                 PAGE_SIZE * nr_gframes,
  96                                 map_pte_fn, &frames);
  97        return rc;
  98}
  99
 100int arch_gnttab_map_status(uint64_t *frames, unsigned long nr_gframes,
 101                           unsigned long max_nr_gframes,
 102                           grant_status_t **__shared)
 103{
 104        int rc;
 105        grant_status_t *shared = *__shared;
 106
 107        if (shared == NULL) {
 108                /* No need to pass in PTE as we are going to do it
 109                 * in apply_to_page_range anyhow. */
 110                struct vm_struct *area =
 111                        alloc_vm_area(PAGE_SIZE * max_nr_gframes, NULL);
 112                BUG_ON(area == NULL);
 113                shared = area->addr;
 114                *__shared = shared;
 115        }
 116
 117        rc = apply_to_page_range(&init_mm, (unsigned long)shared,
 118                                 PAGE_SIZE * nr_gframes,
 119                                 map_pte_fn_status, &frames);
 120        return rc;
 121}
 122
 123void arch_gnttab_unmap(void *shared, unsigned long nr_gframes)
 124{
 125        apply_to_page_range(&init_mm, (unsigned long)shared,
 126                            PAGE_SIZE * nr_gframes, unmap_pte_fn, NULL);
 127}
 128