root/arch/x86/xen/grant-table.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. arch_gnttab_map_shared
  2. arch_gnttab_map_status
  3. arch_gnttab_unmap
  4. arch_gnttab_valloc
  5. arch_gnttab_vfree
  6. arch_gnttab_init
  7. xen_pvh_gnttab_setup

   1 // SPDX-License-Identifier: GPL-2.0 OR MIT
   2 /******************************************************************************
   3  * grant_table.c
   4  * x86 specific part
   5  *
   6  * Granting foreign access to our memory reservation.
   7  *
   8  * Copyright (c) 2005-2006, Christopher Clark
   9  * Copyright (c) 2004-2005, K A Fraser
  10  * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
  11  *                    VA Linux Systems Japan. Split out x86 specific part.
  12  */
  13 
  14 #include <linux/sched.h>
  15 #include <linux/mm.h>
  16 #include <linux/slab.h>
  17 #include <linux/vmalloc.h>
  18 
  19 #include <xen/interface/xen.h>
  20 #include <xen/page.h>
  21 #include <xen/grant_table.h>
  22 #include <xen/xen.h>
  23 
  24 #include <asm/pgtable.h>
  25 
  26 static struct gnttab_vm_area {
  27         struct vm_struct *area;
  28         pte_t **ptes;
  29 } gnttab_shared_vm_area, gnttab_status_vm_area;
  30 
  31 int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
  32                            unsigned long max_nr_gframes,
  33                            void **__shared)
  34 {
  35         void *shared = *__shared;
  36         unsigned long addr;
  37         unsigned long i;
  38 
  39         if (shared == NULL)
  40                 *__shared = shared = gnttab_shared_vm_area.area->addr;
  41 
  42         addr = (unsigned long)shared;
  43 
  44         for (i = 0; i < nr_gframes; i++) {
  45                 set_pte_at(&init_mm, addr, gnttab_shared_vm_area.ptes[i],
  46                            mfn_pte(frames[i], PAGE_KERNEL));
  47                 addr += PAGE_SIZE;
  48         }
  49 
  50         return 0;
  51 }
  52 
  53 int arch_gnttab_map_status(uint64_t *frames, unsigned long nr_gframes,
  54                            unsigned long max_nr_gframes,
  55                            grant_status_t **__shared)
  56 {
  57         grant_status_t *shared = *__shared;
  58         unsigned long addr;
  59         unsigned long i;
  60 
  61         if (shared == NULL)
  62                 *__shared = shared = gnttab_status_vm_area.area->addr;
  63 
  64         addr = (unsigned long)shared;
  65 
  66         for (i = 0; i < nr_gframes; i++) {
  67                 set_pte_at(&init_mm, addr, gnttab_status_vm_area.ptes[i],
  68                            mfn_pte(frames[i], PAGE_KERNEL));
  69                 addr += PAGE_SIZE;
  70         }
  71 
  72         return 0;
  73 }
  74 
  75 void arch_gnttab_unmap(void *shared, unsigned long nr_gframes)
  76 {
  77         pte_t **ptes;
  78         unsigned long addr;
  79         unsigned long i;
  80 
  81         if (shared == gnttab_status_vm_area.area->addr)
  82                 ptes = gnttab_status_vm_area.ptes;
  83         else
  84                 ptes = gnttab_shared_vm_area.ptes;
  85 
  86         addr = (unsigned long)shared;
  87 
  88         for (i = 0; i < nr_gframes; i++) {
  89                 set_pte_at(&init_mm, addr, ptes[i], __pte(0));
  90                 addr += PAGE_SIZE;
  91         }
  92 }
  93 
  94 static int arch_gnttab_valloc(struct gnttab_vm_area *area, unsigned nr_frames)
  95 {
  96         area->ptes = kmalloc_array(nr_frames, sizeof(*area->ptes), GFP_KERNEL);
  97         if (area->ptes == NULL)
  98                 return -ENOMEM;
  99 
 100         area->area = alloc_vm_area(PAGE_SIZE * nr_frames, area->ptes);
 101         if (area->area == NULL) {
 102                 kfree(area->ptes);
 103                 return -ENOMEM;
 104         }
 105 
 106         return 0;
 107 }
 108 
 109 static void arch_gnttab_vfree(struct gnttab_vm_area *area)
 110 {
 111         free_vm_area(area->area);
 112         kfree(area->ptes);
 113 }
 114 
 115 int arch_gnttab_init(unsigned long nr_shared, unsigned long nr_status)
 116 {
 117         int ret;
 118 
 119         if (!xen_pv_domain())
 120                 return 0;
 121 
 122         ret = arch_gnttab_valloc(&gnttab_shared_vm_area, nr_shared);
 123         if (ret < 0)
 124                 return ret;
 125 
 126         /*
 127          * Always allocate the space for the status frames in case
 128          * we're migrated to a host with V2 support.
 129          */
 130         ret = arch_gnttab_valloc(&gnttab_status_vm_area, nr_status);
 131         if (ret < 0)
 132                 goto err;
 133 
 134         return 0;
 135 err:
 136         arch_gnttab_vfree(&gnttab_shared_vm_area);
 137         return -ENOMEM;
 138 }
 139 
 140 #ifdef CONFIG_XEN_PVH
 141 #include <xen/events.h>
 142 #include <xen/xen-ops.h>
 143 static int __init xen_pvh_gnttab_setup(void)
 144 {
 145         if (!xen_pvh_domain())
 146                 return -ENODEV;
 147 
 148         xen_auto_xlat_grant_frames.count = gnttab_max_grant_frames();
 149 
 150         return xen_xlate_map_ballooned_pages(&xen_auto_xlat_grant_frames.pfn,
 151                                              &xen_auto_xlat_grant_frames.vaddr,
 152                                              xen_auto_xlat_grant_frames.count);
 153 }
 154 /* Call it _before_ __gnttab_init as we need to initialize the
 155  * xen_auto_xlat_grant_frames first. */
 156 core_initcall(xen_pvh_gnttab_setup);
 157 #endif

/* [<][>][^][v][top][bottom][index][help] */