2 * Palacios VNET Host Hooks Implementations
6 #include <linux/kernel.h>
7 #include <linux/kthread.h>
8 #include <linux/spinlock.h>
10 #include <linux/sched.h>
11 #include <linux/uaccess.h>
12 #include <linux/init.h>
13 #include <asm/delay.h>
14 #include <linux/timer.h>
16 #include <vnet/vnet.h>
19 #include "palacios-vnet.h"
20 #include "linux-exts.h"
22 static void host_print(const char * fmt, ...) {
23 #if V3_PRINTK_OLD_STYLE_OUTPUT
38 // Allocate space atomically, in case we are called
40 buf = kmalloc(V3_PRINTK_BUF_SIZE, GFP_ATOMIC);
42 printk("palacios: output skipped - unable to allocate\n");
47 vsnprintf(buf,V3_PRINTK_BUF_SIZE, fmt, ap);
50 printk(KERN_INFO "palacios: %s",buf);
60 static void * host_allocate_pages(int num_pages, unsigned int alignment){
62 struct page * pgs = NULL;
63 int order = get_order(num_pages * PAGE_SIZE);
65 pgs = alloc_pages(GFP_KERNEL, order);
67 WARN(!pgs, "Could not allocate pages\n");
69 addr = page_to_pfn(pgs) << PAGE_SHIFT;
75 static void host_free_pages(void * page_paddr, int num_pages) {
76 uintptr_t pg_addr = (uintptr_t)page_paddr;
78 __free_pages(pfn_to_page(pg_addr >> PAGE_SHIFT), get_order(num_pages * PAGE_SIZE));
83 host_alloc(unsigned int size) {
85 addr = kmalloc(size, GFP_KERNEL);
100 host_vaddr_to_paddr(void * vaddr)
102 return (void*) __pa(vaddr);
107 host_paddr_to_vaddr(void * paddr)
114 host_start_kernel_thread(
115 int (*fn)(void * arg),
117 char * thread_name) {
118 struct task_struct * thread = NULL;
120 thread = kthread_run(fn, arg, thread_name );
125 static void host_kthread_sleep(long timeout){
126 set_current_state(TASK_INTERRUPTIBLE);
131 schedule_timeout(timeout);
137 static void host_kthread_wakeup(void * thread){
138 struct task_struct * kthread = (struct task_struct *)thread;
140 wake_up_process(kthread);
143 static void host_kthread_stop(void * thread){
144 struct task_struct * kthread = (struct task_struct *)thread;
146 kthread_stop(kthread);
149 static int host_kthread_should_stop(void){
150 return kthread_should_stop();
154 static void host_udelay(unsigned long usecs){
168 host_mutex_alloc(void)
170 spinlock_t * lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL);
173 spin_lock_init(lock);
188 host_mutex_lock(void * mutex,
191 spin_lock((spinlock_t *)mutex);
195 host_mutex_unlock(void * mutex)
197 spin_unlock((spinlock_t *)mutex);
204 struct timer_list timer;
205 unsigned long interval;
208 void (* timer_fun)(void * private_data);
213 void timeout_fn(unsigned long arg){
214 struct host_timer * timer = (struct host_timer *)arg;
217 timer->timer_fun(timer->pri_data);
219 mod_timer(&(timer->timer), timer->interval);
224 host_create_timer(unsigned long interval,
225 void (* timer_fun)(void * priv_data),
227 struct host_timer * timer = (struct host_timer *)kmalloc(sizeof(struct host_timer), GFP_KERNEL);
229 timer->interval = interval;
230 timer->timer_fun = timer_fun;
231 timer->pri_data = data;
233 init_timer(&(timer->timer));
235 timer->timer.data = (unsigned long)timer;
236 timer->timer.function = timeout_fn;
237 timer->timer.expires = interval;
243 host_start_timer(void * vnet_timer){
244 struct host_timer * timer = (struct host_timer *)vnet_timer;
247 add_timer(&(timer->timer));
251 host_reset_timer(void * vnet_timer, unsigned long interval){
252 struct host_timer * timer = (struct host_timer *)timer;
254 timer->interval = interval;
258 host_stop_timer(void * vnet_timer){
259 struct host_timer * timer = (struct host_timer *)vnet_timer;
262 del_timer(&(timer->timer));
266 host_del_timer(void * vnet_timer){
267 struct host_timer * timer = (struct host_timer *)vnet_timer;
269 del_timer(&(timer->timer));
278 static struct vnet_host_hooks vnet_host_hooks = {
279 .timer_create = host_create_timer,
280 .timer_del = host_del_timer,
281 .timer_start = host_start_timer,
282 .timer_stop = host_stop_timer,
283 .timer_reset = host_reset_timer,
285 .thread_start = host_start_kernel_thread,
286 .thread_sleep = host_kthread_sleep,
287 .thread_wakeup = host_kthread_wakeup,
288 .thread_stop = host_kthread_stop,
289 .thread_should_stop = host_kthread_should_stop,
290 .udelay = host_udelay,
292 .yield_cpu = host_yield_cpu,
293 .mutex_alloc = host_mutex_alloc,
294 .mutex_free = host_mutex_free,
295 .mutex_lock = host_mutex_lock,
296 .mutex_unlock = host_mutex_unlock,
299 .allocate_pages = host_allocate_pages,
300 .free_pages = host_free_pages,
301 .malloc = host_alloc,
303 .vaddr_to_paddr = host_vaddr_to_paddr,
304 .paddr_to_vaddr = host_paddr_to_vaddr,
309 static int vnet_init( void ) {
310 init_vnet(&vnet_host_hooks);
315 INFO("V3 VNET Inited\n");
321 static int vnet_deinit( void ) {
324 vnet_bridge_deinit();
327 INFO("V3 VNET Deinited\n");
332 static struct linux_ext vnet_ext = {
335 .deinit = vnet_deinit,
340 register_extension(&vnet_ext);