Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Context-based output infrastructure (V3_Print, etc) and modifications to use it
[palacios.git] / palacios / src / devices / vnet_guest_iface.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2012, Peter Dinda <pdindal@northwestern.edu>
11  * Copyright (c) 2012, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Peter Dinda <pdinda@northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <palacios/vmm.h>
21 #include <palacios/vmm_dev_mgr.h>
22 #include <palacios/vm_guest_mem.h>
23 #include <vnet/vnet.h>
24 #include <palacios/vmm_sprintf.h>
25 #include <devices/pci.h>
26
27
28 /*
29   The purpose of this device is to act as a back-end for 
30   in-guest implementations of the VNET forwarding and encapsulation engine.
31
32   Via the hypercall hanging off this device, the guest can
33   ask for the appropriate header to use for encapsulation (if any).
34
35   All control-plane work remains in the VNET implementation in Palacios and 
36   the host.  
37 */
38
39 #ifndef V3_CONFIG_DEBUG_VNET_GUEST_IFACE
40 #undef PrintDebug
41 #define PrintDebug(fmt, args...)
42 #endif
43
44
45 /*
46   Calling convention:
47
48 64 bit only:
49   rax = hcall number
50   rbx = 64|32 tag
51   rcx = src
52   rdx = dest_mac
53   rsi = header_ptr
54   rdi = header_len
55   r8  = 0 => send, 1=>recv
56
57 returns rax=negative on error. 0 if successful
58
59 */
60 static int handle_header_query_hcall(struct guest_info * info, uint_t hcall_id, void * priv_data) 
61 {
62     addr_t src_mac_gva;
63     addr_t dest_mac_gva;
64     addr_t header_ptr_gva;
65
66     uint8_t src_mac[6];
67     uint8_t dest_mac[6];
68     uint32_t header_len;
69     int      recv; 
70     uint32_t copy_len;
71
72
73     struct v3_vnet_header vnet_header;
74
75     if (hcall_id != VNET_HEADER_QUERY_HCALL) { 
76         PrintError(info->vm_info, info, "Unknown hcall 0x%x in vnet_stub\n",hcall_id);
77         return -1;
78     }
79
80     src_mac_gva = info->vm_regs.rcx;
81     dest_mac_gva = info->vm_regs.rdx;
82     header_ptr_gva = info->vm_regs.rsi;
83     header_len = info->vm_regs.rdi;
84     recv = info->vm_regs.r8;
85
86     if (v3_read_gva_memory(info,src_mac_gva,6,src_mac)!=6) { 
87         PrintError(info->vm_info, info, "Cannot read src mac in query\n");
88         info->vm_regs.rax=-1;
89         return 0;
90     }
91
92     if (v3_read_gva_memory(info,(addr_t)dest_mac_gva,6,dest_mac)!=6) { 
93         PrintError(info->vm_info, info, "Cannot read src mac in query\n");
94         info->vm_regs.rax=-1;
95         return 0;
96     }
97
98     if (v3_vnet_query_header(src_mac,dest_mac,recv,&vnet_header) < 0 ) { 
99         PrintError(info->vm_info, info, "Failed to lookup header\n");
100         info->vm_regs.rax=-1;
101         return 0;
102     }
103
104     copy_len = (sizeof(vnet_header)<header_len) ? sizeof(vnet_header) : header_len;
105
106     if (v3_write_gva_memory(info,header_ptr_gva,copy_len,(uchar_t*)&vnet_header) != copy_len) { 
107         PrintError(info->vm_info, info, "Failed to write back header\n");
108         info->vm_regs.rax=-1;
109         return 0;
110     }
111
112     info->vm_regs.rax=0;
113     return 0;
114
115 }
116
117 static int vnet_guest_iface_free(void *priv_data) {
118
119     return 0;
120 }
121
122
123 static struct v3_device_ops dev_ops = {
124     .free = vnet_guest_iface_free,
125 };
126
127 static int dev_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) 
128 {
129     char * name = v3_cfg_val(cfg, "name");
130
131     PrintDebug(vm, VCORE_NONE, "VNET guest interface: Initializing as device: %s\n", name);
132
133     struct vm_device * dev = v3_add_device(vm, name, &dev_ops, NULL);
134
135     if (dev == NULL) {
136         PrintError(vm, VCORE_NONE, "Could not attach device %s\n", name);
137         return -1;
138     }
139
140     v3_register_hypercall(vm, VNET_HEADER_QUERY_HCALL, handle_header_query_hcall, NULL);
141
142     return 0;
143 }
144
145
146 device_register("VNET_GUEST_IFACE", dev_init)