mirror of
https://github.com/hermitcore/libhermit.git
synced 2025-03-09 00:00:03 +01:00
Refactored code gen to produce new version of required code (no kernel mallocs). Malloc hooks WIP
This commit is contained in:
parent
ae48d1a6c4
commit
16b9e0583c
14 changed files with 329 additions and 142 deletions
|
@ -56,6 +56,7 @@ typedef struct free_list {
|
|||
* maintaining a value, rather their address is their value.
|
||||
*/
|
||||
extern const void kernel_start;
|
||||
extern const void kernel_end;
|
||||
|
||||
uint8_t * host_kernel_start = NULL;
|
||||
|
||||
|
@ -373,13 +374,28 @@ oom:
|
|||
while(1) {HALT; }
|
||||
}
|
||||
|
||||
int ib_memory_init(void)
|
||||
void * ib_memory_init(void)
|
||||
{
|
||||
LOG_INFO("ib_memory_init\n");
|
||||
|
||||
size_t phyaddr, viraddr, bits;
|
||||
int err;
|
||||
|
||||
/* phyaddr = */
|
||||
phyaddr = (size_t) &kernel_end - IB_MEMORY_SIZE;
|
||||
bits = PG_RW|PG_GLOBAL|PG_NX;
|
||||
viraddr = vma_alloc(IB_MEMORY_NPAGES * PAGE_SIZE, VMA_READ|VMA_WRITE|VMA_CACHEABLE);
|
||||
if (BUILTIN_EXPECT(!viraddr, 0)) {
|
||||
LOG_INFO("BUILTIN_EXPECT failed: ib_memory_init 1\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
err = page_map(viraddr, phyaddr, IB_MEMORY_NPAGES, bits);
|
||||
if (BUILTIN_EXPECT(err, 0)) {
|
||||
LOG_INFO("BUILTIN_EXPECT failed: ib_memory_init 2\n");
|
||||
vma_free(viraddr, viraddr + IB_MEMORY_NPAGES*PAGE_SIZE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LOG_INFO("ib_memory_init\n");
|
||||
return (void *) viraddr;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
/** @brief Initialize the memory subsystem */
|
||||
int memory_init(void);
|
||||
|
||||
/** @brief Initialize the IB memory space */
|
||||
void * ib_memory_init(void);
|
||||
|
||||
/** @brief Request physical page frames */
|
||||
size_t get_pages(size_t npages);
|
||||
|
||||
|
|
32
kernel/ibv.c
32
kernel/ibv.c
|
@ -60,7 +60,7 @@ typedef struct {
|
|||
} __attribute__((packed)) uhyve_ibv_get_device_list_t;
|
||||
|
||||
struct ibv_device ** ibv_get_device_list(int * num_devices) {
|
||||
// num_devices can be mapped to physical memory right away.
|
||||
struct ibv_device ** ret_guest;
|
||||
uhyve_ibv_get_device_list_t uhyve_args;
|
||||
uhyve_args.num_devices = (int *) guest_to_host((size_t) num_devices);
|
||||
|
||||
|
@ -78,9 +78,10 @@ struct ibv_device ** ibv_get_device_list(int * num_devices) {
|
|||
|
||||
uhyve_send(UHYVE_PORT_IBV_GET_DEVICE_LIST, (unsigned) virt_to_phys((size_t) &uhyve_args));
|
||||
|
||||
/* for (int i = 0; i < MAX_NUM_OF_IBV_DEVICES; i++) { */
|
||||
/* host_to_guest_ibv_device(ret_guest[i], GUEST); */
|
||||
/* } */
|
||||
ret_guest = (struct ibv_device **) host_to_guest((size_t) uhyve_args.ret);
|
||||
for (int i = 0; i < *num_devices; i++) {
|
||||
ret_guest[i] = host_to_guest_ibv_device(ret_guest[i], HOST); // TODO: Make this a host_to_guest fcn for lists of ptrs
|
||||
}
|
||||
|
||||
return ret_guest;
|
||||
}
|
||||
|
@ -98,15 +99,16 @@ typedef struct {
|
|||
} __attribute__((packed)) uhyve_ibv_get_device_name_t;
|
||||
|
||||
const char * ibv_get_device_name(struct ibv_device * device) {
|
||||
char * ret_guest;
|
||||
uhyve_ibv_get_device_name_t uhyve_args;
|
||||
uhyve_args.device = guest_to_host_ibv_device(device);
|
||||
|
||||
uhyve_send(UHYVE_PORT_IBV_GET_DEVICE_NAME, (unsigned) virt_to_phys((size_t) &uhyve_args));
|
||||
|
||||
host_to_guest_ibv_device(device, GUEST);
|
||||
ret_guest = host_to_guest((size_t) uhyve_args.ret);
|
||||
ret_guest = (char *) host_to_guest((size_t) uhyve_args.ret);
|
||||
|
||||
return (char *) ret_guest;
|
||||
return ret_guest;
|
||||
}
|
||||
|
||||
|
||||
|
@ -122,18 +124,19 @@ typedef struct {
|
|||
} __attribute__((packed)) uhyve_ibv_open_device_t;
|
||||
|
||||
struct ibv_context * ibv_open_device(struct ibv_device * device) {
|
||||
struct ibv_context * ret_guest;
|
||||
uhyve_ibv_open_device_t uhyve_args;
|
||||
uhyve_args.device = guest_to_host_ibv_device(device);
|
||||
|
||||
ret_guest = kmalloc(sizeof(struct ibv_context));
|
||||
uhyve_args.ret = (struct ibv_context *) guest_to_host((size_t) ret_guest);
|
||||
/* ret_guest = kmalloc(sizeof(struct ibv_context)); */
|
||||
/* uhyve_args.ret = (struct ibv_context *) guest_to_host((size_t) ret_guest); */
|
||||
|
||||
uhyve_send(UHYVE_PORT_IBV_OPEN_DEVICE, (unsigned) virt_to_phys((size_t)&uhyve_args));
|
||||
|
||||
host_to_guest_ibv_device(device, GUEST);
|
||||
host_to_guest_ibv_context((struct ibv_context * ) ret_guest, GUEST);
|
||||
|
||||
return (struct ibv_context *) ret_guest;
|
||||
ret_guest = host_to_guest_ibv_context(uhyve_args.ret, HOST);
|
||||
|
||||
return ret_guest;
|
||||
}
|
||||
|
||||
|
||||
|
@ -177,16 +180,17 @@ typedef struct {
|
|||
} __attribute__((packed)) uhyve_ibv_create_comp_channel_t;
|
||||
|
||||
struct ibv_comp_channel * ibv_create_comp_channel(struct ibv_context * context) {
|
||||
struct ibv_comp_channel * ret_guest;
|
||||
uhyve_ibv_create_comp_channel_t uhyve_args;
|
||||
uhyve_args.context = guest_to_host_ibv_context(context);
|
||||
|
||||
ret_guest = kmalloc(sizeof(struct ibv_comp_channel));
|
||||
uhyve_args.ret = (struct ibv_comp_channel *) guest_to_host((size_t) ret_guest);
|
||||
/* ret_guest = kmalloc(sizeof(struct ibv_comp_channel)); */
|
||||
/* uhyve_args.ret = (struct ibv_comp_channel *) guest_to_host((size_t) ret_guest); */
|
||||
|
||||
uhyve_send(UHYVE_PORT_IBV_CREATE_COMP_CHANNEL, (unsigned) virt_to_phys((size_t) &uhyve_args));
|
||||
|
||||
host_to_guest_ibv_context(context, GUEST);
|
||||
host_to_guest_ibv_comp_channel((struct ibv_comp_channel *) ret_guest, GUEST);
|
||||
ret_guest = host_to_guest_ibv_comp_channel(uhyve_args.ret, HOST);
|
||||
|
||||
return ret_guest;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
#define UHYVE_PORT_IBV_OPEN_DEVICE 0x510,
|
||||
#define UHYVE_PORT_IBV_GET_DEVICE_NAME 0x511,
|
||||
#define UHYVE_PORT_IBV_QUERY_PORT 0x512,
|
||||
#define UHYVE_PORT_IBV_CREATE_COMP_CHANNEL 0x513,
|
||||
#define UHYVE_PORT_IBV_OPEN_DEVICE 0x510
|
||||
#define UHYVE_PORT_IBV_GET_DEVICE_NAME 0x511
|
||||
#define UHYVE_PORT_IBV_QUERY_PORT 0x512
|
||||
#define UHYVE_PORT_IBV_CREATE_COMP_CHANNEL 0x513
|
|
@ -78,3 +78,5 @@ struct ibv_comp_channel * ibv_create_comp_channel(struct ibv_context * context)
|
|||
// TODO: Fix pointers in returned data structures.
|
||||
return uhyve_args.ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
void call_ibv_open_device(struct kvm_run * run, uint8_t * guest_mem) {
|
||||
unsigned data = *((unsigned*)((size_t)run+run->io.data_offset));
|
||||
uhyve_ibv_open_device_t * args = (uhyve_ibv_open_device_t *) (guest_mem + data);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
case UHYVE_PORT_IBV_OPEN_DEVICE:
|
||||
call_ibv_open_device(run, guest_mem);
|
||||
break;
|
||||
|
@ -10,4 +9,4 @@
|
|||
break;
|
||||
case UHYVE_PORT_IBV_CREATE_COMP_CHANNEL:
|
||||
call_ibv_create_comp_channel(run, guest_mem);
|
||||
break;
|
||||
break;
|
||||
|
|
0
tools/ibv_code_generator/__init__.py
Normal file
0
tools/ibv_code_generator/__init__.py
Normal file
|
@ -1,5 +1,6 @@
|
|||
struct ibv_context * ibv_open_device(struct ibv_device * device)
|
||||
const char * ibv_get_device_name(struct ibv_device * device)
|
||||
struct ibv_comp_channel * ibv_create_comp_channel(struct ibv_context * context)
|
||||
int ibv_query_port(struct ibv_context * context,uint8_t port_num,struct ibv_port_attr * port_attr)
|
||||
|
||||
struct ibv_device ** ibv_get_device_list(int * num_devices)
|
||||
|
|
|
@ -88,7 +88,7 @@ Required in: ./tool/uhyve-ibv.h
|
|||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
import pyparsing as pp
|
||||
from parser import generate_struct_conversions
|
||||
|
||||
|
||||
# Path of the input file containing function prototypes.
|
||||
|
@ -101,7 +101,7 @@ UHYVE_IBV_HEADER_GEN_PATH = "GEN-tools-uhyve-ibv-ports.h"
|
|||
INCLUDE_STDDEF_GEN_PATH = "GEN-include-hermit-stddef.h"
|
||||
UHYVE_IBV_HEADER_STRUCTS_GEN_PATH = "GEN-tools-uhyve-ibv-structs.h"
|
||||
UHYVE_HOST_FCNS_GEN_PATH = "GEN-tools-uhyve-ibv.c"
|
||||
VERBS_HEADER_PATH = "verbs-0.h"
|
||||
# VERBS_HEADER_PATH = "verbs-0.h"
|
||||
|
||||
# Starting number of the sequence used for IBV ports.
|
||||
PORT_NUMBER_START = 0x510
|
||||
|
@ -109,64 +109,166 @@ PORT_NUMBER_START = 0x510
|
|||
TABS = ["", "\t", "\t\t", "\t\t\t", "\t\t\t\t"]
|
||||
NEWLINES = ["", "\n", "\n\n"]
|
||||
|
||||
class Type:
|
||||
def __init__(self, string):
|
||||
ts = string
|
||||
if (string[-1] is "*") and (string[-2] is not " "):
|
||||
ts = string[:-1] + " *"
|
||||
|
||||
def get_struct_name(function_name):
|
||||
"""Returns the matching struct name for a given function name.
|
||||
"""
|
||||
return "uhyve_{0}_t".format(function_name)
|
||||
self.type_string = ts
|
||||
self.type_components = ts.split(" ")
|
||||
|
||||
def get_struct_name(self):
|
||||
name = ""
|
||||
if is_struct():
|
||||
name = self.type_components[1]
|
||||
return name
|
||||
|
||||
def is_struct(self):
|
||||
return self.type_components[0] == "struct"
|
||||
|
||||
def is_pointer(self):
|
||||
return self.type_components[-1] == "*"
|
||||
|
||||
def is_void(self):
|
||||
return self.type_string == "void"
|
||||
|
||||
|
||||
def parse_line(line):
|
||||
"""Parses a line containing a function prototype.
|
||||
class FunctionParameter:
|
||||
def __init__(self, string):
|
||||
components = string.split(" ")
|
||||
type_string = " ".join(components[:-1])
|
||||
|
||||
Args:
|
||||
line: Line of the following format:
|
||||
<return_type> <function_name>(<param_type> <param_name>, [...])
|
||||
self.type = Type(type_string)
|
||||
self.name = components[-1]
|
||||
|
||||
Returns:
|
||||
Return type, function name, parameters as Tuple[string, string, list[string]]
|
||||
"""
|
||||
parens_split = line.split("(")
|
||||
def get_full_expression:
|
||||
return self.type.type_string + " " + self.name
|
||||
|
||||
ret_and_name = parens_split[0].split(" ")
|
||||
all_params = parens_split[-1][:-1]
|
||||
def get_struct_name(self):
|
||||
return self.type.get_struct_name()
|
||||
|
||||
ret = " ".join(ret_and_name[:-1])
|
||||
function_name = ret_and_name[-1]
|
||||
def is_struct(self):
|
||||
return self.type.is_struct()
|
||||
|
||||
params = all_params.split(",")
|
||||
params[-1] = params[-1][:-1]
|
||||
|
||||
return ret, function_name, params
|
||||
def is_pointer(self):
|
||||
return self.type.is_pointer()
|
||||
|
||||
|
||||
def generate_struct(ret, function_name, params):
|
||||
"""Generates the struct to hold a function's parameters and return value.
|
||||
class FunctionPrototype:
|
||||
def __init__(self, string):
|
||||
parens_split = string.split("(")
|
||||
ret_and_name = parens_split[0].split(" ")
|
||||
all_params = parens_split[-1].split(")")[0]
|
||||
param_strings = all_params.split(",")
|
||||
|
||||
Args:
|
||||
self.parameters = [FunctionParameter(p) for p in param_strings]
|
||||
self.ret = Type(" ".join(ret_and_name[:-1]))
|
||||
self.function_name = ret_and_name[-1]
|
||||
|
||||
def generate_args_struct(ret, function_name, params):
|
||||
"""Generates the struct to hold a function's parameters and return value.
|
||||
|
||||
Args:
|
||||
ret: Return type as string.
|
||||
function_name: Function name as string.
|
||||
params: Parameters as list of strings.
|
||||
|
||||
Returns:
|
||||
Returns:
|
||||
Generated struct as string.
|
||||
"""
|
||||
struct = "typedef struct {\n"
|
||||
if params:
|
||||
struct += "\t// Parameters:\n"
|
||||
for param in params:
|
||||
struct += "\t{0};\n".format(param)
|
||||
"""
|
||||
code = ""
|
||||
code = "typedef struct {\n"
|
||||
|
||||
if ret is not "void":
|
||||
struct += "\t// Return value:\n"
|
||||
struct += "\t{0} ret;\n".format(ret)
|
||||
if self.get_num_parameters() > 0:
|
||||
code += "\t// Parameters:\n"
|
||||
for param in self.parameters:
|
||||
code += "\t{0};\n".format(param.get_full_expression())
|
||||
|
||||
struct_name = get_struct_name(function_name)
|
||||
struct += "}} __attribute__((packed)) {0};\n\n".format(struct_name)
|
||||
if not self.ret.is_void():
|
||||
code += "\t// Return value:\n"
|
||||
code += "\t{0} ret;\n".format(self.ret.type_string)
|
||||
|
||||
return struct
|
||||
code += "}} __attribute__((packed)) {0};\n\n".format( self.get_args_struct_name())
|
||||
|
||||
return code
|
||||
|
||||
def get_num_parameters(self):
|
||||
return len(self.parameters)
|
||||
|
||||
def get_parameter_types(self):
|
||||
return [param.type.type_string for param in self.parameters]
|
||||
|
||||
def get_port_name(self):
|
||||
return "UHYVE_PORT_" + self.function_name.upper()
|
||||
|
||||
def get_args_struct_name(self):
|
||||
return "uhyve_{0}_t".format(self.function_name)
|
||||
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
# def get_struct_name(function_name):
|
||||
# """Returns the matching struct name for a given function name.
|
||||
# """
|
||||
# return "uhyve_{0}_t".format(function_name)
|
||||
|
||||
|
||||
# def parse_line(line):
|
||||
# """Parses a line containing a function prototype.
|
||||
|
||||
# Args:
|
||||
# line: Line of the following format:
|
||||
# <return_type> <function_name>(<param_type> <param_name>, [...])
|
||||
|
||||
# Returns:
|
||||
# [Return type, function name, parameters] as Tuple[string, string, list[string]]
|
||||
# """
|
||||
# parens_split = line.split("(")
|
||||
|
||||
# ret_and_name = parens_split[0].split(" ")
|
||||
# all_params = parens_split[-1][:-1]
|
||||
|
||||
# ret = " ".join(ret_and_name[:-1])
|
||||
# function_name = ret_and_name[-1]
|
||||
|
||||
# params = all_params.split(",")
|
||||
# params[-1] = params[-1][:-1]
|
||||
|
||||
# return ret, function_name, params
|
||||
|
||||
|
||||
# def generate_struct(ret, function_name, params):
|
||||
# """Generates the struct to hold a function's parameters and return value.
|
||||
|
||||
# Args:
|
||||
# ret: Return type as string.
|
||||
# function_name: Function name as string.
|
||||
# params: Parameters as list of strings.
|
||||
|
||||
# Returns:
|
||||
# Generated struct as string.
|
||||
# """
|
||||
# struct = "typedef struct {\n"
|
||||
# if params:
|
||||
# struct += "\t// Parameters:\n"
|
||||
# for param in params:
|
||||
# struct += "\t{0};\n".format(param)
|
||||
|
||||
# if ret is not "void":
|
||||
# struct += "\t// Return value:\n"
|
||||
# struct += "\t{0} ret;\n".format(ret)
|
||||
|
||||
# struct_name = get_struct_name(function_name)
|
||||
# struct += "}} __attribute__((packed)) {0};\n\n".format(struct_name)
|
||||
|
||||
# return struct
|
||||
|
||||
# TODO: hier gehts weiter
|
||||
def generate_kernel_function(ret, function_name, params):
|
||||
"""Generates the kernel function that sends the KVM exit IO to uhyve.
|
||||
|
||||
|
@ -178,11 +280,16 @@ def generate_kernel_function(ret, function_name, params):
|
|||
Returns:
|
||||
Generated function as string.
|
||||
"""
|
||||
function = "{0} {1}({2}) {{\n".format(ret, function_name, ", ".join(params))
|
||||
code = ""
|
||||
|
||||
code = "{0} {1}({2}) {{\n".format(ret, function_name, ", ".join(params))
|
||||
|
||||
# Create uhyve_args and define parameters
|
||||
struct_name = get_struct_name(function_name)
|
||||
function += "\t{0} uhyve_args;\n".format(struct_name)
|
||||
code += "\t{0} ret_guest;\n".format(ret)
|
||||
code += "\t{0} uhyve_args;\n".format(struct_name)
|
||||
|
||||
# TODO: Make a class for function prototypes
|
||||
for param in params:
|
||||
param_split = param.split(" ")
|
||||
param_type = " ".join(param_split[:-1])
|
||||
|
@ -190,54 +297,64 @@ def generate_kernel_function(ret, function_name, params):
|
|||
|
||||
# Define struct members according to their type.
|
||||
if "**" in param_type:
|
||||
function += "\t// TODO: Take care of ** parameter.\n"
|
||||
code += "\t// TODO: Take care of ** parameter.\n"
|
||||
elif "*" in param_type:
|
||||
function += "\tuhyve_args->{0} = " "({1}) virt_to_phys((size_t) {2});\n".format(
|
||||
param_name, param_type, param_name)
|
||||
# TODO: char ptrs
|
||||
code += "\tuhyve_args.{0} = guest_to_host_{1}({2});\n".format(param_name,
|
||||
param_split[1])
|
||||
else:
|
||||
function += "\tuhyve_args->{0} = {0};\n".format(param_name)
|
||||
|
||||
# Allocate memory for return value if it is a pointer.
|
||||
if "**" in ret:
|
||||
function += "\n\t// TODO: Take care of return value.\n"
|
||||
elif "*" in ret:
|
||||
function += "\n\tuhyve_args->ret = kmalloc(sizeof({0}));\n".format(ret[:-2])
|
||||
code += "\tuhyve_args,{0} = {0};\n".format(param_name)
|
||||
|
||||
# call uhyve_send() using the respective port ID.
|
||||
port_name = "UHYVE_PORT_" + function_name.upper()
|
||||
function += "\n\tuhyve_send({0}, (unsigned) virt_to_phys((size_t) " \
|
||||
code += "\n\tuhyve_send({0}, (unsigned) virt_to_phys((size_t) " \
|
||||
"&uhyve_args));\n\n".format(port_name)
|
||||
|
||||
function += "\t// TODO: Fix pointers in returned data structures.\n"
|
||||
for param in params:
|
||||
param_split = param.split(" ")
|
||||
param_type = " ".join(param_split[:-1])
|
||||
param_name = param_split[-1]
|
||||
|
||||
function += "\treturn uhyve_args.ret;\n"
|
||||
function += "}\n\n\n"
|
||||
# Define struct members according to their type.
|
||||
if "**" in param_type:
|
||||
code += "\t// TODO: Take care of ** parameter.\n"
|
||||
elif "*" in param_type:
|
||||
code += "\thost_to_guest_{0}({1}, GUEST);".format(param_split[1], param_name)
|
||||
|
||||
return function
|
||||
if "**" in ret:
|
||||
code += "\t// TODO: Take care of ** parameter.\n"
|
||||
elif "*" in ret:
|
||||
code += "\tret_guest = host_to_guest_{0}(uhyve_args.ret, HOST)\n".format(ret[1])
|
||||
else:
|
||||
code += "\tret_guest = uhyve_args.ret;\n"
|
||||
|
||||
code += "\n\treturn ret_guest;\n"
|
||||
code += "}\n\n\n"
|
||||
|
||||
return code
|
||||
|
||||
|
||||
def generate_uhyve_cases(function_names):
|
||||
# TODO: done
|
||||
def generate_uhyve_cases(function_prototypes):
|
||||
""" Generates all switch-cases for uhyve's KVM exit IO.
|
||||
|
||||
Args:
|
||||
function_names: All function names as a list of strings.
|
||||
|
||||
Returns:
|
||||
Generated switch-cases as one single string.
|
||||
Generated switch-cases [string]
|
||||
"""
|
||||
cases = ""
|
||||
code = ""
|
||||
|
||||
for function_name in function_names:
|
||||
port_name = "UHYVE_PORT_" + function_name.upper()
|
||||
struct_name = get_struct_name(function_name)
|
||||
for pt in function_prototypes:
|
||||
name = pt.function_name
|
||||
port_name = pt.get_port_name()
|
||||
|
||||
cases += "{0}{1}case {2}:".format(NEWLINES[1], TABS[3], port_name)
|
||||
cases += "{0}{1}call_{2}(run, guest_mem);".format(NEWLINES[1], TABS[4], function_name)
|
||||
cases += "{0}{1}break;".format(NEWLINES[1], TABS[4])
|
||||
code += "{0}{1}case {2}:".format(NEWLINES[1], TABS[3], port_name)
|
||||
code += "{0}{1}call_{2}(run, guest_mem);".format(NEWLINES[1], TABS[4], name)
|
||||
code += "{0}{1}break;".format(NEWLINES[1], TABS[4])
|
||||
|
||||
return cases
|
||||
return code
|
||||
|
||||
|
||||
# TODO: hier gehts weiter
|
||||
def generate_uhyve_host_function(ret, function_name, params):
|
||||
"""Generates a switch-case that catches a KVM exit IO for the given function in uhyve.
|
||||
|
||||
|
@ -273,7 +390,7 @@ def generate_uhyve_host_function(ret, function_name, params):
|
|||
host_param = "{0}".format(param_name)
|
||||
|
||||
return host_param
|
||||
|
||||
|
||||
struct_name = get_struct_name(function_name)
|
||||
|
||||
fcn = "{0}void call_{1}(struct kvm_run * run, uint8_t * guest_mem) {{".format(NEWLINES[1], function_name)
|
||||
|
@ -285,7 +402,7 @@ def generate_uhyve_host_function(ret, function_name, params):
|
|||
fcn += generate_host_call_parameter(param) + ", "
|
||||
else:
|
||||
fcn += generate_host_call_parameter(params[-1]) + ");"
|
||||
|
||||
|
||||
if "**" in ret:
|
||||
fcn += "{0}{1}// TODO: Take care of {2} return value.".format(NEWLINES[1], TABS[1], ret)
|
||||
elif "*" in ret:
|
||||
|
@ -333,35 +450,6 @@ def generate_port_macros(function_names):
|
|||
format(num, "X"))
|
||||
return macros
|
||||
|
||||
def generate_struct_conversions():
|
||||
|
||||
word = pp.Word(pp.alphas+"_", bodyChars=pp.alphanums+"_")
|
||||
|
||||
struct_header = (pp.Literal("struct").suppress() + word +
|
||||
pp.Literal("{").suppress())
|
||||
struct_footer = pp.Literal("};").suppress()
|
||||
|
||||
member_var = word + pp.Literal(";").suppress()
|
||||
member_type = (pp.Combine(pp.OneOrMore(word + ~pp.FollowedBy(pp.Literal(";"))),
|
||||
joinString=" ", adjacent=False)
|
||||
+ pp.ZeroOrMore("*") + pp.FollowedBy(member_var))
|
||||
|
||||
member = pp.Group(member_type + member_var)
|
||||
body = pp.OneOrMore(member)
|
||||
|
||||
struct = struct_header + body + struct_footer
|
||||
|
||||
# TODO: Not bullet proof yet.
|
||||
comment = pp.Or([pp.Literal("/*") + pp.SkipTo(pp.Literal("*/")),
|
||||
pp.Literal("//") + pp.SkipTo(pp.LineEnd())])
|
||||
struct.ignore(comment)
|
||||
|
||||
with open(VERBS_HEADER_PATH, "r") as f_verbs:
|
||||
code = f_verbs.read()
|
||||
|
||||
# for result, _, _ in struct.scanString(code):
|
||||
# print("{0}".format(result))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
"""TODO: Doc
|
||||
|
@ -400,6 +488,3 @@ if __name__ == "__main__":
|
|||
|
||||
generate_struct_conversions()
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
64
tools/ibv_code_generator/parser.py
Normal file
64
tools/ibv_code_generator/parser.py
Normal file
|
@ -0,0 +1,64 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""Copyright (c) 2017, Annika Wierichs, RWTH Aachen University
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the University nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
import pyparsing as pp
|
||||
|
||||
|
||||
VERBS_H_PATH = "verbs-0.h"
|
||||
|
||||
|
||||
def generate_struct_conversions():
|
||||
|
||||
word = pp.Word(pp.alphas+"_", bodyChars=pp.alphanums+"_")
|
||||
|
||||
struct_header = (pp.Literal("struct").suppress() + word +
|
||||
pp.Literal("{").suppress())
|
||||
struct_footer = pp.Literal("};").suppress()
|
||||
|
||||
member_var = word + pp.Literal(";").suppress()
|
||||
member_type = (pp.Combine(pp.OneOrMore(word + ~pp.FollowedBy(pp.Literal(";"))),
|
||||
joinString=" ", adjacent=False)
|
||||
+ pp.ZeroOrMore("*") + pp.FollowedBy(member_var))
|
||||
|
||||
member = pp.Group(member_type + member_var)
|
||||
body = pp.OneOrMore(member)
|
||||
|
||||
struct = struct_header + body + struct_footer
|
||||
|
||||
# TODO: Not bullet proof yet.
|
||||
comment = pp.Or([pp.Literal("/*") + pp.SkipTo(pp.Literal("*/")),
|
||||
pp.Literal("//") + pp.SkipTo(pp.LineEnd())])
|
||||
struct.ignore(comment)
|
||||
|
||||
with open(VERBS_HEADER_PATH, "r") as f_verbs:
|
||||
code = f_verbs.read()
|
||||
|
||||
# for result, _, _ in struct.scanString(code):
|
||||
# print("{0}".format(result))
|
||||
|
|
@ -38,21 +38,26 @@
|
|||
*/
|
||||
|
||||
void call_ibv_get_device_list(struct kvm_run * run, uint8_t * guest_mem) {
|
||||
ib_malloc = true;
|
||||
printf("LOG: UHYVE - call_ibv_get_device_list\n");
|
||||
unsigned data = *((unsigned *)((size_t)run+run->io.data_offset));
|
||||
uhyve_ibv_get_device_list_t * args = (uhyve_ibv_get_device_list_t *) (guest_mem + data);
|
||||
|
||||
// Call IBV function from hypervisor
|
||||
int num_devices;
|
||||
struct ibv_device **host_ret = ibv_get_device_list(&num_devices);
|
||||
/* int num_devices; */
|
||||
/* struct ibv_device **host_ret = ibv_get_device_list(&num_devices); */
|
||||
printf("LOG: UHYVE - call_ibv_get_device_list -- before ibv call\n");
|
||||
args->ret = ibv_get_device_list(args->num_devices);
|
||||
printf("LOG: UHYVE - call_ibv_get_device_list -- after ibv call\n");
|
||||
|
||||
// Copy number of devices and device stucts to kernel memory
|
||||
if (args->num_devices) {
|
||||
memcpy(args->num_devices, &num_devices, sizeof(num_devices));
|
||||
}
|
||||
for (int d = 0; d < num_devices; d++) {
|
||||
memcpy(args->ret[d], host_ret[d], sizeof(struct ibv_device));
|
||||
}
|
||||
// Copy number of devices and device structs to kernel memory
|
||||
/* if (args->num_devices) { */
|
||||
/* memcpy(args->num_devices, &num_devices, sizeof(num_devices)); */
|
||||
/* } */
|
||||
/* for (int d = 0; d < num_devices; d++) { */
|
||||
/* memcpy(args->ret[d], host_ret[d], sizeof(struct ibv_device)); */
|
||||
/* } */
|
||||
ib_malloc = false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,9 +21,12 @@
|
|||
|
||||
#include <infiniband/verbs.h> // Linux include
|
||||
#include <linux/kvm.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define MAX_NUM_OF_IBV_DEVICES 16
|
||||
|
||||
extern bool ib_malloc;
|
||||
|
||||
typedef enum {
|
||||
UHYVE_PORT_IBV_OPEN_DEVICE = 0x510,
|
||||
UHYVE_PORT_IBV_GET_DEVICE_LIST = 0x511,
|
||||
|
@ -38,7 +41,8 @@ typedef struct {
|
|||
// Parameters:
|
||||
int * num_devices;
|
||||
// Return value:
|
||||
struct ibv_device * ret[MAX_NUM_OF_IBV_DEVICES];
|
||||
// struct ibv_device * ret[MAX_NUM_OF_IBV_DEVICES];
|
||||
struct ibv_device ** ret;
|
||||
} __attribute__((packed)) uhyve_ibv_get_device_list_t;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -194,8 +194,8 @@ static __thread struct kvm_run *run = NULL;
|
|||
static __thread int vcpufd = -1;
|
||||
static __thread uint32_t cpuid = 0;
|
||||
|
||||
static bool ib_malloc = false;
|
||||
static uint8_t * ib_mem = NULL;
|
||||
bool ib_malloc = false;
|
||||
|
||||
// Definition of malloc hooks for IBV library
|
||||
static void ib_init_hook(void);
|
||||
|
@ -209,6 +209,7 @@ static void (* default_free_hook)(void *, const void *);
|
|||
/* __malloc_initialize_hook = ib_init_hook; */
|
||||
|
||||
static void ib_init_hook(void) {
|
||||
printf("ib_init_hook\n");
|
||||
default_malloc_hook = __malloc_hook;
|
||||
default_free_hook = __free_hook;
|
||||
|
||||
|
@ -217,15 +218,18 @@ static void ib_init_hook(void) {
|
|||
}
|
||||
|
||||
static void * ib_malloc_hook(size_t size, const void * caller) {
|
||||
printf("ib_malloc_hook");
|
||||
void * result;
|
||||
|
||||
__malloc_hook = default_malloc_hook;
|
||||
__free_hook = default_free_hook;
|
||||
|
||||
if (ib_malloc) {
|
||||
printf(" - ib_malloc true -- ib_mem: %p\n", ib_mem);
|
||||
ib_mem -= size;
|
||||
result = ib_mem;
|
||||
result = (size == 0) ? NULL : ib_mem;
|
||||
} else {
|
||||
printf(" - ib_malloc false\n");
|
||||
result = malloc(size);
|
||||
}
|
||||
|
||||
|
@ -1039,7 +1043,7 @@ static int vcpu_loop(void)
|
|||
}
|
||||
|
||||
// InfiniBand
|
||||
case UHYVE_PORT_IBV_GET_DEVICE_LIST: {
|
||||
case UHYVE_PORT_IBV_GET_DEVICE_LIST:
|
||||
printf("LOG: UHYVE CASE\n");
|
||||
call_ibv_get_device_list(run, guest_mem);
|
||||
break;
|
||||
|
@ -1060,8 +1064,6 @@ static int vcpu_loop(void)
|
|||
call_ibv_create_comp_channel(run, guest_mem);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
default:
|
||||
err(1, "KVM: unhandled KVM_EXIT_IO at port 0x%x, direction %d\n", run->io.port, run->io.direction);
|
||||
break;
|
||||
|
@ -1492,7 +1494,10 @@ int uhyve_init(char *path)
|
|||
err(1, "unable to initialized network");
|
||||
}
|
||||
|
||||
printf("ib_mem initialization\n");
|
||||
ib_mem = guest_mem + guest_size;
|
||||
printf("guest_mem: %p, guest_size: %p\n", guest_mem, guest_size);
|
||||
printf("ib_mem = guest_mem + guest_size: %p\n", ib_mem);
|
||||
ib_init_hook();
|
||||
|
||||
return ret;
|
||||
|
|
Loading…
Add table
Reference in a new issue