platform.c
Go to the documentation of this file.
1 /*
2  * Bareflank Hypervisor
3  *
4  * Copyright (C) 2015 Assured Information Security, Inc.
5  * Author: Rian Quinn <quinnr@ainfosec.com>
6  * Author: Brendan Kerrigan <kerriganb@ainfosec.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include <debug.h>
24 #include <platform.h>
25 #include <bfelf_loader.h>
26 
27 #include <linux/mm.h>
28 #include <linux/slab.h>
29 #include <linux/string.h>
30 #include <linux/module.h>
31 #include <linux/vmalloc.h>
32 #include <linux/version.h>
33 #include <linux/cpumask.h>
34 #include <linux/sched.h>
35 #include <linux/kallsyms.h>
36 
37 #include <asm/tlbflush.h>
38 
39 typedef long (*set_affinity_fn)(pid_t, const struct cpumask *);
41 
42 void *
43 platform_alloc_rw(uint64_t len)
44 {
45  void *addr = NULL;
46 
47  if (len == 0)
48  {
49  ALERT("platform_alloc_rw: invalid length\n");
50  return addr;
51  }
52 
53  addr = vmalloc(len);
54 
55  if (addr == NULL)
56  ALERT("platform_alloc_rw: failed to vmalloc mem: %lld\n", len);
57 
58  return addr;
59 }
60 
61 void *
62 platform_alloc_rwe(uint64_t len)
63 {
64  void *addr = NULL;
65 
66  if (len == 0)
67  {
68  ALERT("platform_alloc_rwe: invalid length\n");
69  return addr;
70  }
71 
72  addr = __vmalloc(len, GFP_KERNEL, PAGE_KERNEL_EXEC);
73 
74  if (addr == NULL)
75  ALERT("platform_alloc_rwe: failed to vmalloc executable mem: %lld\n", len);
76 
77  return addr;
78 }
79 
80 void
81 platform_free_rw(void *addr, uint64_t len)
82 {
83  (void) len;
84 
85  if (addr == NULL)
86  {
87  ALERT("platform_free_rw: invalid address %p\n", addr);
88  return;
89  }
90 
91  vfree(addr);
92 }
93 
94 void
95 platform_free_rwe(void *addr, uint64_t len)
96 {
97  (void) len;
98 
99  if (addr == NULL)
100  {
101  ALERT("platform_free_rwe: invalid address %p\n", addr);
102  return;
103  }
104 
105  vfree(addr);
106 }
107 
108 void *
110 {
111  if (is_vmalloc_addr(virt))
112  return (void *)page_to_phys(vmalloc_to_page(virt));
113  else
114  return (void *)virt_to_phys(virt);
115 }
116 
117 void
118 platform_memset(void *ptr, char value, uint64_t num)
119 {
120  if (!ptr)
121  return;
122 
123  memset(ptr, value, num);
124 }
125 
126 void
127 platform_memcpy(void *dst, const void *src, uint64_t num)
128 {
129  if (!dst || !src)
130  return;
131 
132  memcpy(dst, src, num);
133 }
134 
135 void
137 {
138 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0)
139  cr4_init_shadow();
140 #endif
141 }
142 
143 void
145 {
146 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0)
147  cr4_init_shadow();
148 #endif
149 }
150 
151 int64_t
153 {
154  int64_t num_cpus = num_online_cpus();
155 
156  if (num_cpus < 0)
157  return 0;
158 
159  return num_cpus;
160 }
161 
162 int64_t
163 platform_set_affinity(int64_t affinity)
164 {
165  if (!set_cpu_affinity)
166  {
167  set_cpu_affinity = (set_affinity_fn)kallsyms_lookup_name("sched_setaffinity");
168  if (set_cpu_affinity == NULL)
169  {
170  ALERT("Failed to locate sched_setaffinity\n");
171  return BF_ERROR_UNKNOWN;
172  }
173  }
174 
175  if (set_cpu_affinity(current->pid, cpumask_of(affinity)) != 0)
176  return BF_ERROR_UNKNOWN;
177 
178  return affinity;
179 }
180 
181 void
182 platform_restore_affinity(int64_t affinity)
183 {
184  (void) affinity;
185 }
void * memset(void *block, int c, size_t size)
void platform_start(void)
Definition: platform.c:136
void platform_free_rwe(void *addr, uint64_t len)
Definition: platform.c:95
set_affinity_fn set_cpu_affinity
Definition: platform.c:40
void platform_memset(void *ptr, char value, uint64_t num)
Definition: platform.c:118
void platform_stop(void)
Definition: platform.c:144
void * platform_alloc_rw(uint64_t len)
Definition: platform.c:43
int64_t platform_num_cpus(void)
Definition: platform.c:152
constexpr const auto addr
Definition: cpuid_x64.h:80
int64_t platform_set_affinity(int64_t affinity)
Definition: platform.c:163
void platform_restore_affinity(int64_t affinity)
Definition: platform.c:182
#define ALERT(...)
Definition: debug.h:156
void * platform_alloc_rwe(uint64_t len)
Definition: platform.c:62
constexpr const auto current
Definition: vcpuid.h:36
constexpr page_table_x64::integer_pointer virt
long(* set_affinity_fn)(pid_t, const struct cpumask *)
Definition: platform.c:39
void platform_memcpy(void *dst, const void *src, uint64_t num)
Definition: platform.c:127
void platform_free_rw(void *addr, uint64_t len)
Definition: platform.c:81
void * platform_virt_to_phys(void *virt)
Definition: platform.c:109
#define BF_ERROR_UNKNOWN
Definition: error_codes.h:115