diff --git a/arch/x86/mm/memory.c b/arch/x86/mm/memory.c index 629afc022..84da0f6d6 100644 --- a/arch/x86/mm/memory.c +++ b/arch/x86/mm/memory.c @@ -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; } diff --git a/include/hermit/memory.h b/include/hermit/memory.h index 89ed45f0c..762de0b9c 100644 --- a/include/hermit/memory.h +++ b/include/hermit/memory.h @@ -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); diff --git a/kernel/ibv.c b/kernel/ibv.c index 9a87c85d0..3190dc515 100644 --- a/kernel/ibv.c +++ b/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; } diff --git a/tools/ibv_code_generator/GEN-include-hermit-stddef.h b/tools/ibv_code_generator/GEN-include-hermit-stddef.h index 88c558bd3..3e1b9533c 100644 --- a/tools/ibv_code_generator/GEN-include-hermit-stddef.h +++ b/tools/ibv_code_generator/GEN-include-hermit-stddef.h @@ -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, \ No newline at end of file +#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 \ No newline at end of file diff --git a/tools/ibv_code_generator/GEN-kernel-ibv.c b/tools/ibv_code_generator/GEN-kernel-ibv.c index 86675af12..699e9e659 100644 --- a/tools/ibv_code_generator/GEN-kernel-ibv.c +++ b/tools/ibv_code_generator/GEN-kernel-ibv.c @@ -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; } + + diff --git a/tools/ibv_code_generator/GEN-tools-uhyve-ibv.c b/tools/ibv_code_generator/GEN-tools-uhyve-ibv.c index 6c8a78439..e5ec8a6a4 100644 --- a/tools/ibv_code_generator/GEN-tools-uhyve-ibv.c +++ b/tools/ibv_code_generator/GEN-tools-uhyve-ibv.c @@ -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); diff --git a/tools/ibv_code_generator/GEN-tools-uhyve.c b/tools/ibv_code_generator/GEN-tools-uhyve.c index 79c075eee..845868592 100644 --- a/tools/ibv_code_generator/GEN-tools-uhyve.c +++ b/tools/ibv_code_generator/GEN-tools-uhyve.c @@ -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; \ No newline at end of file + break; diff --git a/tools/ibv_code_generator/__init__.py b/tools/ibv_code_generator/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tools/ibv_code_generator/function-prototypes-1.txt b/tools/ibv_code_generator/function-prototypes-1.txt index 3072b0496..fe4a06dea 100644 --- a/tools/ibv_code_generator/function-prototypes-1.txt +++ b/tools/ibv_code_generator/function-prototypes-1.txt @@ -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) diff --git a/tools/ibv_code_generator/generate-code.py b/tools/ibv_code_generator/generate-code.py index ab45ea4ec..9add6f23e 100755 --- a/tools/ibv_code_generator/generate-code.py +++ b/tools/ibv_code_generator/generate-code.py @@ -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: - ( , [...]) + 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: + # ( , [...]) + + # 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() - - - diff --git a/tools/ibv_code_generator/parser.py b/tools/ibv_code_generator/parser.py new file mode 100644 index 000000000..6c43c8c38 --- /dev/null +++ b/tools/ibv_code_generator/parser.py @@ -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)) + diff --git a/tools/uhyve-ibv.c b/tools/uhyve-ibv.c index 3f77c1d50..56b2d2be8 100644 --- a/tools/uhyve-ibv.c +++ b/tools/uhyve-ibv.c @@ -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; } diff --git a/tools/uhyve-ibv.h b/tools/uhyve-ibv.h index efc3181fa..8f410c07f 100644 --- a/tools/uhyve-ibv.h +++ b/tools/uhyve-ibv.h @@ -21,9 +21,12 @@ #include // Linux include #include +#include #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 { diff --git a/tools/uhyve.c b/tools/uhyve.c index 68a1fce2b..adca6088b 100644 --- a/tools/uhyve.c +++ b/tools/uhyve.c @@ -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;