Date: Thu, 7 Aug 2014 18:34:11 GMT From: dpl@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r272045 - soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw Message-ID: <201408071834.s77IYBPY016606@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dpl Date: Thu Aug 7 18:34:11 2014 New Revision: 272045 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=272045 Log: Generally working on the JITter. Modified: soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc Modified: soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc ============================================================================== --- soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc Thu Aug 7 18:33:18 2014 (r272044) +++ soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc Thu Aug 7 18:34:11 2014 (r272045) @@ -1,11 +1,13 @@ -/* JIT compilation code */ #undef _KERNEL #include <iostream> #include <string> #include <vector> #include <llvm/ADT/OwningPtr.h> +#include <llvm/ADT/ArrayRef.h> #include <llvm/Bitcode/ReaderWriter.h> +#include <llvm/CodeGen/MachineCodeInfo.h> +#include <llvm/ExecutionEngine/ExecutionEngine.h> #include <llvm/IR/IRBuilder.h> #include <llvm/IR/LLVMContext.h> #include <llvm/IR/Module.h> @@ -18,6 +20,7 @@ #include <missing.h> #include <sys/mbuf.h> +#include <sys/types.h> #include <netinet/ip_fw.h> #include <netinet/ip_dummynet.h> #include <netinet/in_pcb.h> @@ -27,7 +30,6 @@ #include <netpfil/ipfw/ip_fw_private.h> } - typedef int (*funcptr)(); using namespace llvm; @@ -39,11 +41,26 @@ LLVMContext con; OwningPtr<MemoryBuffer> buffer; IRBuilder<> irb; - std::vector<BasicBlock> BBs; + std::vector<BasicBlock*> blocks; + + // Vars Types + Type *int8Ty; + Type *int16Ty; + Type *int32Ty; + + // JIT Compiled Vars + Value *match; + Value *l; + Value *done; + Value *f_pos; + Value *retval; + + // Functions used by our JITed code. + Function *iface_match; + // Load the bc for JIT compilation. Module *loadbc(std::string name) { - /* We load the bc for JIT compilation */ error_code ec = MemoryBuffer::getFile(name, buffer); if (ec) { std::cerr << "Failed to open bitcode: " << ec.message() << "\n"; @@ -60,32 +77,49 @@ return (mod); } - /* Set the needed variables to perform pkt filtering. */ + // Create the needed variables to perform pkt filtering. int - setVars() + setEnv() { - //We need the match var. - Value *match; - Value *f_pos; + // Get Type objects + int8Ty = Type::getInt8Ty(con); + int16Ty = Type::getInt16Ty(con); + int32Ty = Type::getInt32Ty(con); + + // Get StrucType from bitcode. + + // Store vars. + match = irb.CreateAlloca(int32Ty); + l = irb.CreateAlloca(int32Ty); + done = irb.CreateAlloca(int32Ty); + f_pos = irb.CreateAlloca(int32Ty); + retval = irb.CreateAlloca(int32Ty); + + // Create needed GlobalVariables. + + // Get Function defs from bitcode. + iface_match = mod->getFunction("iface_match"); + return (0); } - public: + public: ipfwJIT(): irb(con) { - //Create the module and load the code. + // Create the module and load the code. mod = loadbc("ip_fw_rules.bc"); - setVars(); - //Create Function, and start its first BasicBlock. - //int ipfw_chk_jitted(ip_fw_args *); - // XXX Do we have to define ip_fw_args using this? - StructType ipfwargsTy = StructType::get(/*TYPE1, TYPE2, TYPE3...*/); - Type *argsTy[] = { PointerType::getUnqual(ipfwargsTy) }; - FunctionType *ipfwchkTy = FunctionType::get(Int32Ty, argsTy, false); - func = Function::Create(ipfwchkTy, GlobalValue::PrivateLinkage, "ipfw_chk", mod); - - // XXX Create basic block, and add it to BBs + func = mod->getFunction("ipfw_chk_jit"); + func->setLinkage(GlobalValue::ExternalLinkage); + // Create the entry point of the function + BasicBlock *entry = BasicBlock::Create(con, "entry", func); + // Add the entry block to ArrayRef + blocks.push_back(entry); + // Set the IRBuilder to insert instructions after the basic block. + irb.SetInsertPoint(entry); + // Get struct types, and store vars + setEnv(); + // From on on, it's just a matter of emitting the code for each rule/action. } ~ipfwJIT() { @@ -93,63 +127,86 @@ delete mod; } + funcptr + functionPtr() + { + MachineCodeInfo machinf; + + ExecutionEngine::runJITOnFunction(func, &machinf); + return ((funcptr)machinf.address()); + } + int - emit_nop(int *match) + emit_nop(int *matchptr) { - /* - static IPFW_RULES_INLINE void - rule_nop(int *match) - { - *match = 1; - } - // Get the stub (prototype) for the cell function - F = Mod->getFunction("cell"); - // Set it to have private linkage, so that it can be removed after being - // inlined. - F->setLinkage(GlobalValue::PrivateLinkage); - - // Add an entry basic block to this function and set it - BasicBlock *entry = BasicBlock::Create(C, "entry", F); - B.SetInsertPoint(entry); - // Cache the type of registers - regTy = Type::getInt16Ty(C); - - // Collect the function parameters - auto args = F->arg_begin(); - oldGrid = args++; - newGrid = args++; - width = args++; - height = args++; - x = args++; - y = args++; + // static IPFW_RULES_INLINE void + // rule_nop(int *match) + // { + // *match = 1; + // } - // Create space on the stack for the local registers - for (int i=0 ; i<10 ; i++) - { - a[i] = B.CreateAlloca(regTy); - } + *matchptr = 1; - // Create a space on the stack for the current value. This can be - // assigned to, and will be returned at the end. Store the value passed - // as a parameter in this. - v = B.CreateAlloca(regTy); - B.CreateStore(args++, v); - // Create a load of pointers to the global registers. - Value *gArg = args; - for (int i=0 ; i<10 ; i++) - { - B.CreateStore(ConstantInt::get(regTy, 0), a[i]); - g[i] = B.CreateConstGEP1_32(gArg, i); - } - */ + irb.CreateStore(ConstantInt::get(int32Ty, 1), match); return (0); } int - emit_forward_mac() + emit_forward_mac(u_int8_t opcode) { + // printf("ipfw: opcode %d unimplemented\n", + // opcode); + + Function *printf; + + printf = mod->getFunction("printf"); + irb.CreateCall(printf, "ipfw: opcode %d unimplemented\n", opcode); return (0); } + + int + emit_jail() + { + // static IPFW_RULES_INLINE void + // rule_jail(int * match, u_short offset, uint8_t proto, ipfw_insn *cmd, struct ip_fw_args *args, int ucred_lookup, void *ucred_cache) + // { + // /* + // * We only check offset == 0 && proto != 0, + // * as this ensures that we have a + // * packet with the ports info. + // */ + // if (offset != 0) + // return; + // if (proto == IPPROTO_TCP || + // proto == IPPROTO_UDP) + // *match = check_uidgid( + // (ipfw_insn_u32 *)cmd, + // args, &ucred_lookup, + // #ifdef __FreeBSD__ + // //(struct bsd_ucred **)&ucred_cache); + // (struct ucred **)&ucred_cache); + // #else + // (void *)&ucred_cache); + // #endif + // } + + return (0); + } + + int + emit_recv() + { + // static IPFW_RULES_INLINE void + // rule_recv(int *match, ipfw_insn *cmd, struct mbuf *m, struct ip_fw_chain *chain, uint32_t *tablearg) + // { + // *match = iface_match(m->m_pkthdr.rcvif, (ipfw_insn_if *)cmd, chain, tablearg); + // } + + irb.CreateStore(irb.CreateCall4(/*STUFF GOING HERE*/ match); + + return (0); + } + }; extern "C" funcptr @@ -157,33 +214,16 @@ { int res; ipfwJIT comp; - Module *mod; int f_pos = 0; int retval = 0; - // Now I have to load the stubs of the loaded rules. // Iterate through the rules. - if (args->rule.slot) { - /* - * Packet has already been tagged as a result of a previous - * match on rule args->rule aka args->rule_id (PIPE, QUEUE, - * REASS, NETGRAPH, DIVERT/TEE...) - * Validate the slot and continue from the next one - * if still present, otherwise do a lookup. - */ - f_pos = (args->rule.chain_id == chain->id) ? - args->rule.slot : - ipfw_find_rule(chain, args->rule.rulenum, - args->rule.rule_id); - } else { - f_pos = 0; - } int done = 0; /* flag to exit the outer loop */ int pktlen = args->m->m_pkthdr.len; - // Iterate through the rules. + // For all the number of rules. for (; f_pos < chain->n_rules; f_pos++) { ipfw_insn *cmd; int l, cmdlen, skip_or; /* skip rest of OR block */ @@ -194,6 +234,7 @@ continue; skip_or = 0; + // For each different command. for (l = f->cmd_len, cmd = f->cmd ; l > 0 ; l -= cmdlen, cmd += cmdlen) { int match; @@ -225,15 +266,16 @@ break; case O_FORWARD_MAC: - comp.emit_forward_mac(); + comp.emit_forward_mac(cmd->opcode); break; -/* XXX + case O_GID: case O_UID: case O_JAIL: comp.emit_jail(); break; +/* XXX case O_RECV: comp.emit_recv(); break; @@ -635,6 +677,8 @@ printf("ipfw: ouch!, skip past end of rules, denying packet\n"); } + // Once we're done iterating through the rules, return the pointer. + return (0); } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201408071834.s77IYBPY016606>