dde_linux: update lxip to 4.4.3

Issue #1974.
This commit is contained in:
Josef Söntgen 2016-05-18 18:49:02 +02:00 committed by Christian Helmuth
parent b9e7fb1edf
commit bcefc874d6
38 changed files with 2805 additions and 2164 deletions

View File

@ -39,7 +39,7 @@ namespace Lxip {
*
* \return Reference to Socketcall object
*/
Socketcall & init(char *address_config);
Socketcall & init(char const *address_config);
typedef Genode::uint8_t uint8_t;
typedef Genode::uint16_t uint16_t;

View File

@ -0,0 +1,35 @@
LXIP_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/lib/lxip
SRC_DIR := $(REP_DIR)/src/lib/lxip
# architecture-dependent includes
ifeq ($(filter-out $(SPECS),x86),)
ARCH_SRC_INC_DIR += $(REP_DIR)/src/include/spec/x86
ifeq ($(filter-out $(SPECS),32bit),)
ARCH_SRC_INC_DIR += $(REP_DIR)/src/include/spec/x86_32
endif # 32bit
ifeq ($(filter-out $(SPECS),64bit),)
ARCH_SRC_INC_DIR += $(REP_DIR)/src/include/spec/x86_64
endif # 64bit
endif # x86
ifeq ($(filter-out $(SPECS),arm),)
ARCH_SRC_INC_DIR += $(REP_DIR)/src/include/spec/arm
ifeq ($(filter-out $(SPECS),arm_v6),)
ARCH_SRC_INC_DIR += $(REP_DIR)/src/include/spec/arm_v6
endif # arm_v6
ifeq ($(filter-out $(SPECS),arm_v7),)
ARCH_SRC_INC_DIR += $(REP_DIR)/src/include/spec/arm_v7
endif # arm_v7
endif # arm
#
# The order of include-search directories is important, we need to look into
# 'contrib' before falling back to our custom 'lx_emul.h' header.
#
INC_DIR += $(SRC_DIR) \
$(SRC_DIR)/include
INC_DIR += $(REP_DIR)/src/include
INC_DIR += $(ARCH_SRC_INC_DIR)
INC_DIR += $(LXIP_CONTRIB_DIR)/include \
$(LXIP_CONTRIB_DIR)/include/uapi \
INC_DIR += $(LIB_CACHE_DIR)/lxip_include/include/include/include

View File

@ -3,19 +3,11 @@ SHARED_LIB = yes
LIB_DIR = $(REP_DIR)/src/lib/lxip
LIB_INC_DIR = $(LIB_DIR)/include
LIBS += lx
LIBS += lxip_include
LX_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/lib/lxip
NET_DIR := $(LX_CONTRIB_DIR)/net
#
# The order of include-search directories is important, we need to look into
# 'contrib' before falling back to our custom 'lx_emul.h' header.
#
INC_DIR += $(LIB_INC_DIR)
INC_DIR += $(LX_CONTRIB_DIR)/include $(LX_CONTRIB_DIR)/include/uapi \
$(LX_CONTRIB_DIR)
CC_OLEVEL = -O2
SETUP_SUFFIX =
@ -34,10 +26,12 @@ CC_C_OPT += -Wno-unused-but-set-variable -Wno-pointer-sign
CC_C_OPT += -include $(LIB_INC_DIR)/lx_emul.h
CC_CXX_OPT = -fpermissive
SRC_CC = dummies.cc env.cc lxcc_emul.cc nic_handler.cc socket_handler.cc \
SRC_CC = dummies.cc lxcc_emul.cc nic_handler.cc socket_handler.cc \
timer_handler.cc
SRC_C += driver.c dummies_c.c init.c lxc_emul.c socket.c
SRC_CC += malloc.cc printf.cc
SRC_C += driver.c dummies_c.c lxc_emul.c
SRC_C += net/802/p8023.c
SRC_C += $(addprefix net/core/,$(notdir $(wildcard $(NET_DIR)/core/*.c)))
@ -46,6 +40,7 @@ SRC_C += net/ethernet/eth.c
SRC_C += net/netlink/af_netlink.c
SRC_C += net/sched/sch_generic.c
SRC_C += lib/checksum.c
SRC_C += lib/rhashtable.c
SRC_C += drivers/net/loopback.c
# DHCP support
@ -53,41 +48,9 @@ SRC_C += net/ipv4/ipconfig.c
#SRC_C = net/ipv4/inet_connection_sock.c
#
# Determine the header files included by the contrib code. For each
# of these header files we create a symlink to 'lx_emul.h'.
#
GEN_INCLUDES := $(shell grep -rh "^\#include .*\/" $(LX_CONTRIB_DIR) |\
sed "s/^\#include [^<\"]*[<\"]\([^>\"]*\)[>\"].*/\1/" | sort | uniq)
#
# Filter out original Linux headers that exist in the contrib directory
#
NO_GEN_INCLUDES := $(shell cd $(LX_CONTRIB_DIR); find -name "*.h" | sed "s/.\///" | sed "s/.*include\///")
GEN_INCLUDES := $(filter-out $(NO_GEN_INCLUDES),$(GEN_INCLUDES))
#
# Put Linux headers in 'GEN_INC' dir, since some include use "../../" paths use
# three level include hierarchy
#
GEN_INC := $(shell pwd)/include/include/include
$(shell mkdir -p $(GEN_INC))
GEN_INCLUDES := $(addprefix $(GEN_INC)/,$(GEN_INCLUDES))
INC_DIR += $(GEN_INC)
#
# Make sure to create the header symlinks prior building
#
$(SRC_C:.c=.o) $(SRC_CC:.cc=.o): $(GEN_INCLUDES)
net/ethernet/eth.o: SETUP_SUFFIX="_eth"
$(GEN_INCLUDES):
$(VERBOSE)mkdir -p $(dir $@)
$(VERBOSE)ln -s $(LIB_INC_DIR)/lx_emul.h $@
vpath %.c $(LX_CONTRIB_DIR)
vpath %.c $(LIB_DIR)
vpath %.cc $(LIB_DIR)
vpath %.cc $(REP_DIR)/src/lx_kit

View File

@ -0,0 +1,35 @@
ifeq ($(called_from_lib_mk),yes)
LXIP_CONTRIB_DIR := $(call select_from_ports,dde_linux)/src/lib/lxip
LX_EMUL_H := $(REP_DIR)/src/lib/lxip/include/lx_emul.h
#
# Determine the header files included by the contrib code. For each
# of these header files we create a symlink to 'lx_emul.h'.
#
GEN_INCLUDES := $(shell grep -rh "^\#include" $(LXIP_CONTRIB_DIR) |\
sed "s/^\#include [^<\"]*[<\"]\([^>\"]*\)[>\"].*/\1/" |\
sort | uniq)
#
# Filter out original Linux headers that exist in the contrib directory
#
NO_GEN_INCLUDES := $(shell cd $(LXIP_CONTRIB_DIR)/; find include -name "*.h" |\
sed "s/.\///" | sed "s/.*include\///")
GEN_INCLUDES := $(filter-out $(NO_GEN_INCLUDES),$(GEN_INCLUDES))
#
# Put Linux headers in 'GEN_INC' dir, since some include use "../../" paths use
# three level include hierarchy
#
GEN_INC := $(shell pwd)/include/include/include
GEN_INCLUDES := $(addprefix $(GEN_INC)/,$(GEN_INCLUDES))
all: $(GEN_INCLUDES)
$(GEN_INCLUDES):
$(VERBOSE)mkdir -p $(dir $@)
$(VERBOSE)ln -s $(LX_EMUL_H) $@
endif
# vi: set ft=make :

View File

@ -1,141 +1,153 @@
linux-3.9/drivers/net/loopback.c
linux-3.9/include/asm-generic/bitops/non-atomic.h
linux-3.9/include/linux/errqueue.h
linux-3.9/include/linux/etherdevice.h
linux-3.9/include/linux/ethtool.h
linux-3.9/include/linux/icmp.h
linux-3.9/include/linux/if_arp.h
linux-3.9/include/linux/if_ether.h
linux-3.9/include/linux/if_link.h
linux-3.9/include/linux/inetdevice.h
linux-3.9/include/linux/jhash.h
linux-3.9/include/linux/list.h
linux-3.9/include/linux/list_nulls.h
linux-3.9/include/linux/netdev_features.h
linux-3.9/include/linux/netdevice.h
linux-3.9/include/linux/net.h
linux-3.9/include/linux/netlink.h
linux-3.9/include/linux/skbuff.h
linux-3.9/include/linux/socket.h
linux-3.9/include/linux/swab.h
linux-3.9/include/linux/tcp.h
linux-3.9/include/linux/udp.h
linux-3.9/include/net/arp.h
linux-3.9/include/net/datalink.h
linux-3.9/include/net/dsfield.h
linux-3.9/include/net/dst.h
linux-3.9/include/net/dst_ops.h
linux-3.9/include/net/flow.h
linux-3.9/include/net/icmp.h
linux-3.9/include/net/inet_connection_sock.h
linux-3.9/include/net/inet_frag.h
linux-3.9/include/net/inet_hashtables.h
linux-3.9/include/net/inetpeer.h
linux-3.9/include/net/inet_sock.h
linux-3.9/include/net/inet_timewait_sock.h
linux-3.9/include/net/ipconfig.h
linux-3.9/include/net/ip_fib.h
linux-3.9/include/net/ip.h
linux-3.9/include/net/neighbour.h
linux-3.9/include/net/netlink.h
linux-3.9/include/net/netns/ipv4.h
linux-3.9/include/net/netns/mib.h
linux-3.9/include/net/ping.h
linux-3.9/include/net/pkt_sched.h
linux-3.9/include/net/protocol.h
linux-3.9/include/net/raw.h
linux-3.9/include/net/request_sock.h
linux-3.9/include/net/route.h
linux-3.9/include/net/sch_generic.h
linux-3.9/include/net/snmp.h
linux-3.9/include/net/sock.h
linux-3.9/include/net/tcp.h
linux-3.9/include/net/tcp_states.h
linux-3.9/include/net/timewait_sock.h
linux-3.9/include/net/udp.h
linux-3.9/include/net/udplite.h
linux-3.9/include/uapi/asm-generic/socket.h
linux-3.9/include/uapi/linux/byteorder/little_endian.h
linux-3.9/include/uapi/linux/errqueue.h
linux-3.9/include/uapi/linux/ethtool.h
linux-3.9/include/uapi/linux/fib_rules.h
linux-3.9/include/uapi/linux/gen_stats.h
linux-3.9/include/uapi/linux/icmp.h
linux-3.9/include/uapi/linux/if_addr.h
linux-3.9/include/uapi/linux/if_arp.h
linux-3.9/include/uapi/linux/if_ether.h
linux-3.9/include/uapi/linux/if.h
linux-3.9/include/uapi/linux/if_link.h
linux-3.9/include/uapi/linux/if_packet.h
linux-3.9/include/uapi/linux/in6.h
linux-3.9/include/uapi/linux/inet_diag.h
linux-3.9/include/uapi/linux/in.h
linux-3.9/include/uapi/linux/in_route.h
linux-3.9/include/uapi/linux/ip.h
linux-3.9/include/uapi/linux/neighbour.h
linux-3.9/include/uapi/linux/netconf.h
linux-3.9/include/uapi/linux/netdevice.h
linux-3.9/include/uapi/linux/netfilter.h
linux-3.9/include/uapi/linux/net.h
linux-3.9/include/uapi/linux/netlink.h
linux-3.9/include/uapi/linux/pkt_sched.h
linux-3.9/include/uapi/linux/route.h
linux-3.9/include/uapi/linux/rtnetlink.h
linux-3.9/include/uapi/linux/snmp.h
linux-3.9/include/uapi/linux/socket.h
linux-3.9/include/uapi/linux/sockios.h
linux-3.9/include/uapi/linux/swab.h
linux-3.9/include/uapi/linux/tcp.h
linux-3.9/include/uapi/linux/udp.h
linux-3.9/lib/checksum.c
linux-3.9/net/802/p8023.c
linux-3.9/net/core/datagram.c
linux-3.9/net/core/dev_addr_lists.c
linux-3.9/net/core/dev.c
linux-3.9/net/core/dst.c
linux-3.9/net/core/ethtool.c
linux-3.9/net/core/iovec.c
linux-3.9/net/core/neighbour.c
linux-3.9/net/core/net-sysfs.h
linux-3.9/net/core/request_sock.c
linux-3.9/net/core/skbuff.c
linux-3.9/net/core/sock.c
linux-3.9/net/core/stream.c
linux-3.9/net/core/utils.c
linux-3.9/net/ethernet/eth.c
linux-3.9/net/ipv4/af_inet.c
linux-3.9/net/ipv4/arp.c
linux-3.9/net/ipv4/devinet.c
linux-3.9/net/ipv4/fib_frontend.c
linux-3.9/net/ipv4/fib_lookup.h
linux-3.9/net/ipv4/fib_semantics.c
linux-3.9/net/ipv4/fib_trie.c
linux-3.9/net/ipv4/icmp.c
linux-3.9/net/ipv4/inet_connection_sock.c
linux-3.9/net/ipv4/inet_fragment.c
linux-3.9/net/ipv4/inet_hashtables.c
linux-3.9/net/ipv4/inetpeer.c
linux-3.9/net/ipv4/ipconfig.c
linux-3.9/net/ipv4/ip_forward.c
linux-3.9/net/ipv4/ip_fragment.c
linux-3.9/net/ipv4/ip_input.c
linux-3.9/net/ipv4/ip_options.c
linux-3.9/net/ipv4/ip_output.c
linux-3.9/net/ipv4/ip_sockglue.c
linux-3.9/net/ipv4/ping.c
linux-3.9/net/ipv4/protocol.c
linux-3.9/net/ipv4/raw.c
linux-3.9/net/ipv4/route.c
linux-3.9/net/ipv4/tcp_cong.c
linux-3.9/net/ipv4/tcp_cubic.c
linux-3.9/net/ipv4/tcp_diag.c
linux-3.9/net/ipv4/tcp_input.c
linux-3.9/net/ipv4/tcp_ipv4.c
linux-3.9/net/ipv4/tcp_minisocks.c
linux-3.9/net/ipv4/tcp.c
linux-3.9/net/ipv4/tcp_output.c
linux-3.9/net/ipv4/tcp_timer.c
linux-3.9/net/ipv4/udp_impl.h
linux-3.9/net/ipv4/udp.c
linux-3.9/net/netlink/af_netlink.c
linux-3.9/net/sched/sch_generic.c
linux-4.4.3/drivers/net/loopback.c
linux-4.4.3/include/asm-generic/atomic64.h
linux-4.4.3/include/asm-generic/bitops/__ffs.h
linux-4.4.3/include/asm-generic/bitops/__fls.h
linux-4.4.3/include/asm-generic/bitops/ffs.h
linux-4.4.3/include/asm-generic/bitops/fls.h
linux-4.4.3/include/asm-generic/bitops/fls64.h
linux-4.4.3/include/asm-generic/bitops/non-atomic.h
linux-4.4.3/include/linux/errqueue.h
linux-4.4.3/include/linux/etherdevice.h
linux-4.4.3/include/linux/ethtool.h
linux-4.4.3/include/linux/icmp.h
linux-4.4.3/include/linux/if_arp.h
linux-4.4.3/include/linux/if_ether.h
linux-4.4.3/include/linux/if_link.h
linux-4.4.3/include/linux/inetdevice.h
linux-4.4.3/include/linux/jhash.h
linux-4.4.3/include/linux/list.h
linux-4.4.3/include/linux/list_nulls.h
linux-4.4.3/include/linux/log2.h
linux-4.4.3/include/linux/netdev_features.h
linux-4.4.3/include/linux/netdevice.h
linux-4.4.3/include/linux/net.h
linux-4.4.3/include/linux/netlink.h
linux-4.4.3/include/linux/rbtree.h
linux-4.4.3/include/linux/rhashtable.h
linux-4.4.3/include/linux/skbuff.h
linux-4.4.3/include/linux/socket.h
linux-4.4.3/include/linux/swab.h
linux-4.4.3/include/linux/tcp.h
linux-4.4.3/include/linux/udp.h
linux-4.4.3/include/net/arp.h
linux-4.4.3/include/net/datalink.h
linux-4.4.3/include/net/dsfield.h
linux-4.4.3/include/net/dst.h
linux-4.4.3/include/net/dst_metadata.h
linux-4.4.3/include/net/dst_ops.h
linux-4.4.3/include/net/flow.h
linux-4.4.3/include/net/icmp.h
linux-4.4.3/include/net/inet_connection_sock.h
linux-4.4.3/include/net/inet_frag.h
linux-4.4.3/include/net/inet_hashtables.h
linux-4.4.3/include/net/inetpeer.h
linux-4.4.3/include/net/inet_sock.h
linux-4.4.3/include/net/inet_timewait_sock.h
linux-4.4.3/include/net/ipconfig.h
linux-4.4.3/include/net/ip_fib.h
linux-4.4.3/include/net/ip.h
linux-4.4.3/include/net/neighbour.h
linux-4.4.3/include/net/netlink.h
linux-4.4.3/include/net/netns/ipv4.h
linux-4.4.3/include/net/netns/mib.h
linux-4.4.3/include/net/ping.h
linux-4.4.3/include/net/pkt_sched.h
linux-4.4.3/include/net/protocol.h
linux-4.4.3/include/net/raw.h
linux-4.4.3/include/net/request_sock.h
linux-4.4.3/include/net/route.h
linux-4.4.3/include/net/sch_generic.h
linux-4.4.3/include/net/snmp.h
linux-4.4.3/include/net/sock.h
linux-4.4.3/include/net/tcp.h
linux-4.4.3/include/net/tcp_states.h
linux-4.4.3/include/net/timewait_sock.h
linux-4.4.3/include/net/udp.h
linux-4.4.3/include/net/udplite.h
linux-4.4.3/include/uapi/asm-generic/socket.h
linux-4.4.3/include/uapi/linux/byteorder/little_endian.h
linux-4.4.3/include/uapi/linux/errqueue.h
linux-4.4.3/include/uapi/linux/ethtool.h
linux-4.4.3/include/uapi/linux/fib_rules.h
linux-4.4.3/include/uapi/linux/gen_stats.h
linux-4.4.3/include/uapi/linux/icmp.h
linux-4.4.3/include/uapi/linux/if_addr.h
linux-4.4.3/include/uapi/linux/if_arp.h
linux-4.4.3/include/uapi/linux/if_ether.h
linux-4.4.3/include/uapi/linux/if.h
linux-4.4.3/include/uapi/linux/if_link.h
linux-4.4.3/include/uapi/linux/if_packet.h
linux-4.4.3/include/uapi/linux/in6.h
linux-4.4.3/include/uapi/linux/inet_diag.h
linux-4.4.3/include/uapi/linux/in.h
linux-4.4.3/include/uapi/linux/in_route.h
linux-4.4.3/include/uapi/linux/ip.h
linux-4.4.3/include/uapi/linux/neighbour.h
linux-4.4.3/include/uapi/linux/netconf.h
linux-4.4.3/include/uapi/linux/netdevice.h
linux-4.4.3/include/uapi/linux/netfilter.h
linux-4.4.3/include/uapi/linux/net.h
linux-4.4.3/include/uapi/linux/netlink.h
linux-4.4.3/include/uapi/linux/pkt_sched.h
linux-4.4.3/include/uapi/linux/route.h
linux-4.4.3/include/uapi/linux/rtnetlink.h
linux-4.4.3/include/uapi/linux/snmp.h
linux-4.4.3/include/uapi/linux/socket.h
linux-4.4.3/include/uapi/linux/sockios.h
linux-4.4.3/include/uapi/linux/swab.h
linux-4.4.3/include/uapi/linux/tcp.h
linux-4.4.3/include/uapi/linux/udp.h
linux-4.4.3/lib/checksum.c
linux-4.4.3/lib/rbtree.c
linux-4.4.3/lib/rhashtable.c
linux-4.4.3/net/802/p8023.c
linux-4.4.3/net/core/datagram.c
linux-4.4.3/net/core/dev_addr_lists.c
linux-4.4.3/net/core/dev.c
linux-4.4.3/net/core/dst.c
linux-4.4.3/net/core/ethtool.c
linux-4.4.3/net/core/neighbour.c
linux-4.4.3/net/core/net-sysfs.h
linux-4.4.3/net/core/request_sock.c
linux-4.4.3/net/core/skbuff.c
linux-4.4.3/net/core/sock.c
linux-4.4.3/net/core/stream.c
linux-4.4.3/net/core/utils.c
linux-4.4.3/net/ethernet/eth.c
linux-4.4.3/net/ipv4/af_inet.c
linux-4.4.3/net/ipv4/arp.c
linux-4.4.3/net/ipv4/devinet.c
linux-4.4.3/net/ipv4/fib_frontend.c
linux-4.4.3/net/ipv4/fib_lookup.h
linux-4.4.3/net/ipv4/fib_semantics.c
linux-4.4.3/net/ipv4/fib_trie.c
linux-4.4.3/net/ipv4/icmp.c
linux-4.4.3/net/ipv4/inet_connection_sock.c
linux-4.4.3/net/ipv4/inet_fragment.c
linux-4.4.3/net/ipv4/inet_hashtables.c
linux-4.4.3/net/ipv4/inetpeer.c
linux-4.4.3/net/ipv4/ipconfig.c
linux-4.4.3/net/ipv4/ip_forward.c
linux-4.4.3/net/ipv4/ip_fragment.c
linux-4.4.3/net/ipv4/ip_input.c
linux-4.4.3/net/ipv4/ip_options.c
linux-4.4.3/net/ipv4/ip_output.c
linux-4.4.3/net/ipv4/ip_sockglue.c
linux-4.4.3/net/ipv4/ping.c
linux-4.4.3/net/ipv4/protocol.c
linux-4.4.3/net/ipv4/raw.c
linux-4.4.3/net/ipv4/route.c
linux-4.4.3/net/ipv4/tcp_cong.c
linux-4.4.3/net/ipv4/tcp_cubic.c
linux-4.4.3/net/ipv4/tcp_diag.c
linux-4.4.3/net/ipv4/tcp_input.c
linux-4.4.3/net/ipv4/tcp_ipv4.c
linux-4.4.3/net/ipv4/tcp_minisocks.c
linux-4.4.3/net/ipv4/tcp.c
linux-4.4.3/net/ipv4/tcp_output.c
linux-4.4.3/net/ipv4/tcp_timer.c
linux-4.4.3/net/ipv4/udp_impl.h
linux-4.4.3/net/ipv4/udp.c
linux-4.4.3/net/netlink/af_netlink.c
linux-4.4.3/net/netlink/af_netlink.h
linux-4.4.3/net/sched/sch_generic.c

View File

@ -0,0 +1,23 @@
diff --git a/include/net/request_sock.h b/include/net/request_sock.h
index a0dde04..dccc51f 100644
--- a/include/net/request_sock.h
+++ b/include/net/request_sock.h
@@ -109,7 +109,7 @@ reqsk_alloc(const struct request_sock_ops *ops, struct sock *sk_listener,
static inline void reqsk_free(struct request_sock *req)
{
/* temporary debugging */
- WARN_ON_ONCE(atomic_read(&req->rsk_refcnt) != 0);
+ // WARN_ON_ONCE(atomic_read(&req->rsk_refcnt) != 0);
req->rsk_ops->destructor(req);
if (req->rsk_listener)
@@ -120,7 +120,8 @@ static inline void reqsk_free(struct request_sock *req)
static inline void reqsk_put(struct request_sock *req)
{
- if (atomic_dec_and_test(&req->rsk_refcnt))
+ if (atomic_dec_and_test(&req->rsk_refcnt)
+ || req->rsk_refcnt.counter == 1)
reqsk_free(req);
}

View File

@ -0,0 +1,13 @@
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 5c5db66..6cb68a1 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -764,6 +764,8 @@ int inet_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
sock_rps_record_flow(sk);
+ if (sk->sk_wq == 0) sk->sk_wq = sock->wq;
+
err = sk->sk_prot->recvmsg(sk, msg, size, flags & MSG_DONTWAIT,
flags & ~MSG_DONTWAIT, &addr_len);
if (err >= 0)

View File

@ -1,35 +0,0 @@
commit 1843c9d95c0a7f6cf04357bf26633cfd2e5bdda4
Author: Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
Date: Mon Jun 2 13:34:18 2014 +0200
skbuff.patch
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -414,23 +414,9 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
unsigned int fragsz = SKB_DATA_ALIGN(length + NET_SKB_PAD) +
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
- if (fragsz <= PAGE_SIZE && !(gfp_mask & (__GFP_WAIT | GFP_DMA))) {
- void *data;
-
- if (sk_memalloc_socks())
- gfp_mask |= __GFP_MEMALLOC;
-
- data = __netdev_alloc_frag(fragsz, gfp_mask);
-
- if (likely(data)) {
- skb = build_skb(data, fragsz);
- if (unlikely(!skb))
- put_page(virt_to_head_page(data));
- }
- } else {
- skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask,
- SKB_ALLOC_RX, NUMA_NO_NODE);
- }
+ skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask,
+ SKB_ALLOC_RX, NUMA_NO_NODE);
+
if (likely(skb)) {
skb_reserve(skb, NET_SKB_PAD);
skb->dev = dev;

View File

@ -0,0 +1,13 @@
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 9147f9f..c63ee5c 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -3281,7 +3281,7 @@ static inline void skb_remcsum_process(struct sk_buff *skb, void *ptr,
if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) {
__skb_checksum_complete(skb);
- skb_postpull_rcsum(skb, skb->data, ptr - (void *)skb->data);
+ skb_postpull_rcsum(skb, skb->data, (unsigned char*)ptr - skb->data);
}
delta = remcsum_adjust(ptr, skb->csum, start, offset);

View File

@ -1,32 +0,0 @@
From 8b2f74f2258b62ca0e62656cdccbc9159aeab893 Mon Sep 17 00:00:00 2001
From: Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
Date: Tue, 6 Aug 2013 16:12:54 +0200
Subject: [PATCH] L4Linux: Increase TCP-window size
TCP window size is calculated by the amount of memory within L4Linux, use a
larger window size to allow acceptable performance even on smaller VMs.
---
net/ipv4/tcp.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index e220207..29613bf 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3648,6 +3648,13 @@ void __init tcp_init(void)
tcp_init_mem(&init_net);
/* Set per-socket limits to no more than 1/128 the pressure threshold */
limit = nr_free_buffer_pages() << (PAGE_SHIFT - 7);
+
+ /*
+ * Adjust limit so it performs well on systems with little memory. If
+ * this causes errors increase L4Linux main memory
+ */
+ limit = limit < 1024U * 1024 ? 1024U * 1024 : limit;
+
max_wshare = min(4UL*1024*1024, limit);
max_rshare = min(6UL*1024*1024, limit);
--
1.8.4

View File

@ -1 +1 @@
0391d74c0aa610098907fafca8ef399875a12a70
9f095930834c35a2dfc8eaf58b6905081f206c34

View File

@ -54,7 +54,8 @@ HASH_INPUT += $(REP_DIR)/intel_fb.list
# mac80211 stack, iwlwifi sources
#
SRC_DIR_WIFI := src/lib/wifi
URL(wifi) := https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.4.3.tar.xz
VERSION_WIFI := 4.4.3
URL(wifi) := https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-$(VERSION_WIFI).tar.xz
SHA(wifi) := 336d66925a15ce9077cbf2c38acbdc6c2644e33f
DIR(wifi) := $(SRC_DIR_WIFI)
TAR_OPT(wifi) := --strip-components=1 --files-from $(REP_DIR)/wifi.list
@ -64,9 +65,9 @@ HASH_INPUT += $(REP_DIR)/wifi.list
# IP stack sources
#
SRC_DIR_LXIP := src/lib/lxip
VERSION_LXIP := 3.9
URL(lxip) := http://www.kernel.org/pub/linux/kernel/v3.x/linux-$(VERSION_LXIP).tar.gz
SHA(lxip) := 7979f0d670838d0552c7ede5cc06497b81dcd812
VERSION_LXIP := 4.4.3
URL(lxip) := http://www.kernel.org/pub/linux/kernel/v4.x/linux-$(VERSION_LXIP).tar.xz
SHA(lxip) := 336d66925a15ce9077cbf2c38acbdc6c2644e33f
DIR(lxip) := $(SRC_DIR_LXIP)
TAR_OPT(lxip) := --strip-components=1 --files-from $(REP_DIR)/lxip.list
HASH_INPUT += $(REP_DIR)/lxip.list
@ -155,11 +156,12 @@ PATCHES += $(addprefix patches/,$(notdir $(wildcard $(REP_DIR)/patches/usb*.patc
#IP stack
LXIP_OPT = -p1 -d$(SRC_DIR_LXIP)
PATCH_OPT(patches/lxip_icmp.patch) := $(LXIP_OPT)
PATCH_OPT(patches/lxip_ip_config.patch) := $(LXIP_OPT)
PATCH_OPT(patches/lxip_skbuff.patch) := $(LXIP_OPT)
PATCH_OPT(patches/lxip_tcp.patch) := $(LXIP_OPT)
PATCH_OPT(patches/lxip_netlink.patch) := $(LXIP_OPT)
PATCH_OPT(patches/lxip_icmp.patch) := $(LXIP_OPT)
PATCH_OPT(patches/lxip_ip_config.patch) := $(LXIP_OPT)
PATCH_OPT(patches/lxip_netlink.patch) := $(LXIP_OPT)
PATCH_OPT(patches/lxip_request_sock.patch) := $(LXIP_OPT)
PATCH_OPT(patches/lxip_sk_wq.patch) := $(LXIP_OPT)
PATCH_OPT(patches/lxip_skbuff_cast.patch) := $(LXIP_OPT)
# WIFI
WIFI_OPT = -p1 -d$(SRC_DIR_WIFI)

View File

@ -0,0 +1,149 @@
set use_usb_driver [expr [have_spec omap4] || [have_spec arndale] || [have_spec rpi]]
set use_nic_driver [expr [have_spec linux] || [expr !$use_usb_driver && ![have_spec imx53] && ![have_spec hw_odroid_xu] && ![have_spec linux] && ![have_spec hw_wand_quad]]]
requires_installation_of lynx
#
# Build
#
set build_components {
core init
drivers/timer drivers/nic
test/lxip/http_srv
}
lappend_if $use_usb_driver build_components drivers/usb
lappend_if [have_spec gpio] build_components drivers/gpio
source ${genode_dir}/repos/base/run/platform_drv.inc
append_platform_drv_build_components
build $build_components
create_boot_directory
#
# Generate config
#
set config {
<config verbose="yes">
<parent-provides>
<service name="ROM"/>
<service name="RAM"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="CAP"/>
<service name="PD"/>
<service name="RM"/>
<service name="CPU"/>
<service name="LOG"/>
<service name="SIGNAL"/>
</parent-provides>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<start name="timer">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Timer"/> </provides>
</start>
<start name="test-lxip_http_srv">
<resource name="RAM" quantum="8M"/>
<config ld_verbose="yes">
<libc stdout="/dev/log" stderr="/dev/log" ip_addr="10.0.2.55" gateway="10.0.2.1" netmask="255.255.255.0">
<vfs> <dir name="dev"> <log/> </dir> </vfs>
</libc>
</config>
</start>}
append_if [have_spec gpio] config {
<start name="gpio_drv">
<resource name="RAM" quantum="4M"/>
<provides><service name="Gpio"/></provides>
<config/>
</start>}
append_if $use_usb_driver config {
<start name="usb_drv">
<resource name="RAM" quantum="12M"/>
<provides>
<service name="Nic"/>
</provides>
<config ehci="yes">
<nic mac="02:00:00:00:01:01" />
</config>
</start>}
append_platform_drv_config
append_if $use_nic_driver config {
<start name="nic_drv">
<resource name="RAM" quantum="4M"/>
<provides><service name="Nic"/></provides>
</start>}
append config {
</config>
}
install_config $config
#
# Boot modules
#
# generic modules
set boot_modules {
core init timer
ld.lib.so libc.lib.so lxip.lib.so test-lxip_http_srv
libc_resolv.lib.so
}
# platform-specific modules
lappend_if $use_usb_driver boot_modules usb_drv
lappend_if $use_nic_driver boot_modules nic_drv
lappend_if [have_spec gpio] boot_modules gpio_drv
append_platform_drv_boot_modules
build_boot_image $boot_modules
#
# Execute test case
#
# qemu config
append qemu_args " -m 128 -nographic "
append_if [have_spec x86] qemu_args " -net nic,model=e1000 "
append_if [have_spec lan9118] qemu_args " -net nic,model=lan9118 "
append qemu_args " -net user -redir tcp:5555::80 "
run_genode_until forever
set match_string "ipaddr=(\[0-9\]+\.\[0-9\]+\.\[0-9\]+\.\[0-9\]+).*\n"
run_genode_until $match_string 30
if {[have_include "power_on/qemu"]} {
set uri "http://localhost:5555/"
} else {
regexp $match_string $output all ip_addr
set uri "http://$ip_addr:80/"
}
puts "http server is up, try to query website $uri"
set website [exec lynx -dump $uri]
puts "response:\n$website"
if {![regexp {Welcome to our HTTP demonstration server!} $website dummy]} {
puts stderr "Query returned unexpected website"
exit 2;
}
# vi: set ft=tcl :

View File

@ -0,0 +1,125 @@
set use_usb_driver [expr [have_spec omap4] || [have_spec arndale] || [have_spec rpi]]
set use_nic_driver [expr [have_spec linux] || [expr !$use_usb_driver && ![have_spec imx53] && ![have_spec hw_odroid_xu] && ![have_spec linux] && ![have_spec hw_wand_quad]]]
#
# Build
#
set build_components {
core init
drivers/timer drivers/nic
test/lxip/udp_echo
}
lappend_if $use_usb_driver build_components drivers/usb
lappend_if [have_spec gpio] build_components drivers/gpio
source ${genode_dir}/repos/base/run/platform_drv.inc
append_platform_drv_build_components
build $build_components
create_boot_directory
#
# Generate config
#
set config {
<config verbose="yes">
<parent-provides>
<service name="ROM"/>
<service name="RAM"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
<service name="CAP"/>
<service name="PD"/>
<service name="RM"/>
<service name="CPU"/>
<service name="LOG"/>
<service name="SIGNAL"/>
</parent-provides>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<start name="timer">
<resource name="RAM" quantum="1M"/>
<provides> <service name="Timer"/> </provides>
</start>
<start name="test-lxip_udp_echo">
<resource name="RAM" quantum="2M"/>
<config ld_verbose="yes">
<libc stdout="/dev/log" stderr="/dev/log" ip_addr="10.0.2.55" gateway="10.0.2.1" netmask="255.255.255.0">
<vfs> <dir name="dev"> <log/> </dir> </vfs>
</libc>
</config>
</start>}
append_if [have_spec gpio] config {
<start name="gpio_drv">
<resource name="RAM" quantum="4M"/>
<provides><service name="Gpio"/></provides>
<config/>
</start>}
append_if $use_usb_driver config {
<start name="usb_drv">
<resource name="RAM" quantum="12M"/>
<provides>
<service name="Nic"/>
</provides>
<config ehci="yes">
<nic mac="02:00:00:00:01:01" />
</config>
</start>}
append_platform_drv_config
append_if $use_nic_driver config {
<start name="nic_drv">
<resource name="RAM" quantum="4M"/>
<provides><service name="Nic"/></provides>
</start>}
append config {
</config>
}
install_config $config
#
# Boot modules
#
# generic modules
set boot_modules {
core init timer
ld.lib.so libc.lib.so lxip.lib.so test-lxip_udp_echo
libc_resolv.lib.so
}
# platform-specific modules
lappend_if $use_usb_driver boot_modules usb_drv
lappend_if $use_nic_driver boot_modules nic_drv
lappend_if [have_spec gpio] boot_modules gpio_drv
append_platform_drv_boot_modules
build_boot_image $boot_modules
#
# Execute test case
#
# qemu config
append qemu_args " -m 128 -nographic "
append_if [have_spec x86] qemu_args " -net nic,model=e1000 "
append_if [have_spec lan9118] qemu_args " -net nic,model=lan9118 "
append qemu_args " -net user -redir tcp:5555::80 "
run_genode_until forever
# vi: set ft=tcl :

View File

@ -18,7 +18,7 @@
#include <os/config.h>
#include <util/string.h>
extern void create_lxip_plugin(char *address_config);
extern void create_lxip_plugin(char const *address_config);
void __attribute__((constructor)) init_libc_lxip(void)
{
@ -26,7 +26,7 @@ void __attribute__((constructor)) init_libc_lxip(void)
char netmask_str[16] = {0};
char gateway_str[16] = {0};
char address_buf[128];
char *address_config;
char const *address_config;
try {
Genode::Xml_node libc_node = Genode::config()->xml_node().sub_node("libc");

View File

@ -81,7 +81,7 @@ struct Plugin : Libc::Plugin
/**
* Constructor
*/
Plugin(char *address_config);
Plugin(char const *address_config);
bool supports_select(int nfds,
fd_set *readfds,
@ -138,7 +138,7 @@ struct Plugin : Libc::Plugin
};
Plugin::Plugin(char *address_config) : socketcall(Lxip::init(address_config))
Plugin::Plugin(char const *address_config) : socketcall(Lxip::init(address_config))
{
PDBG("using the lxip libc plugin");
}
@ -649,7 +649,7 @@ int Plugin::translate_ops_linux(int optname)
} /* unnamed namespace */
void create_lxip_plugin(char *address_config)
void create_lxip_plugin(char const *address_config)
{
static Plugin lxip_plugin(address_config);
}

View File

@ -6,27 +6,31 @@
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
* Copyright (C) 2013-2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Linux includes */
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
/* local includes */
#include <lx_emul.h>
#include <nic.h>
static struct net_device *_dev;
static int driver_net_open(struct net_device *dev)
{
printk("%s called\n",__func__);
_dev = dev;
return 0;
}
int driver_net_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct net_device_stats *stats = (struct net_device_stats*) netdev_priv(dev);
@ -52,37 +56,6 @@ int driver_net_xmit(struct sk_buff *skb, struct net_device *dev)
}
void net_driver_rx(void *addr, unsigned long size)
{
struct net_device_stats *stats;
if (!_dev)
return;
stats = (struct net_device_stats*) netdev_priv(_dev);
/* allocate skb */
struct sk_buff *skb = dev_alloc_skb(size + 4);
if (!skb) {
printk(KERN_NOTICE "genode_net_rx: low on mem - packet dropped!\n");
stats->rx_dropped++;
return;
}
/* copy packet */
memcpy(skb_put(skb, size), addr, size);
skb->dev = _dev;
skb->protocol = eth_type_trans(skb, _dev);
skb->ip_summed = CHECKSUM_NONE;
netif_receive_skb(skb);
stats->rx_packets++;
stats->rx_bytes += size;
}
static const struct net_device_ops driver_net_ops =
{
.ndo_open = driver_net_open,
@ -118,6 +91,42 @@ out:
return err;
}
module_init(driver_init);
/**
* Called by Nic_client when a packet was received
*/
void net_driver_rx(void *addr, unsigned long size)
{
struct net_device_stats *stats;
if (!_dev)
return;
stats = (struct net_device_stats*) netdev_priv(_dev);
/* allocate skb */
enum {
ADDITIONAL_HEADROOM = 4, /* smallest value found by trial & error */
};
struct sk_buff *skb = dev_alloc_skb(size + ADDITIONAL_HEADROOM);
if (!skb) {
printk(KERN_NOTICE "genode_net_rx: low on mem - packet dropped!\n");
stats->rx_dropped++;
return;
}
/* copy packet */
memcpy(skb_put(skb, size), addr, size);
skb->dev = _dev;
skb->protocol = eth_type_trans(skb, _dev);
skb->ip_summed = CHECKSUM_NONE;
netif_receive_skb(skb);
stats->rx_packets++;
stats->rx_bytes += size;
}

View File

@ -5,13 +5,16 @@
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
* Copyright (C) 2013-2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/printf.h>
#include <base/sleep.h>
extern "C" {
typedef long DUMMY;
@ -20,6 +23,7 @@ enum {
SHOW_DUMMY = 0,
SHOW_SKIP = 0,
SHOW_RET = 0,
SHOW_SHOW = 1,
};
#define DUMMY(retval, name) \
@ -43,6 +47,22 @@ enum {
return retval; \
}
#define DUMMY_SHOW(retval, name) \
DUMMY name(void) { \
if (SHOW_SHOW) \
PWRN( #name " called (from %p) return %d", __builtin_return_address(0), retval); \
return retval; \
}
#define DUMMY_STOP(retval, name) \
DUMMY name(void) { \
do { \
PWRN( #name " called (from %p) stopped", __builtin_return_address(0)); \
Genode::sleep_forever(); \
} while (0); \
return retval; \
}
/*
* Changed return values
@ -76,6 +96,7 @@ DUMMY_RET(0, vlan_tx_tag_present)
DUMMY_RET(1, xfrm4_policy_check)
DUMMY_RET(0, xfrm_sk_clone_policy)
DUMMY_RET(0, xfrm_decode_session_reverse)
DUMMY_RET(1, try_module_get) /* important in sk_prot_alloc() */
/*
@ -114,7 +135,7 @@ DUMMY_SKIP(-1, smp_mb)
DUMMY_SKIP(-1, smp_rmb)
DUMMY_SKIP(-1, smp_wmb)
DUMMY_SKIP(-1, spin_lock_irqsave)
DUMMY_SKIP( 1, spin_trylock)
DUMMY_RET( 1, spin_trylock)
DUMMY_SKIP(-1, spin_unlock_irqrestore)
DUMMY_SKIP(-1, synchronize_rcu)
DUMMY_SKIP(-1, trace_kfree_skb)
@ -207,8 +228,6 @@ DUMMY(-1, dump_stack)
DUMMY(-1, ether_addr_equal_64bits)
DUMMY(-1, exit_fn)
DUMMY(-1, file_inode)
DUMMY(-1, finish_wait)
DUMMY(-1, __fls)
DUMMY(-1, fls64)
DUMMY(-1, free_pages)
DUMMY(-1, from_kgid)
@ -222,7 +241,10 @@ DUMMY(-1, gen_kill_estimator)
DUMMY(-1, get_current_groups)
DUMMY(-1, get_ds)
DUMMY(-1, __get_free_pages)
DUMMY(-1, get_fs)
DUMMY_SKIP(0, get_fs)
DUMMY_SKIP(0, set_fs)
DUMMY(-1, get_net_ns_by_fd)
DUMMY(-1, get_net_ns_by_pid)
DUMMY(-1, getnstimeofday)
@ -238,8 +260,7 @@ DUMMY(-1, hlist_add_before_rcu)
DUMMY(-1, hlist_nulls_del)
DUMMY(-1, hlist_nulls_empty)
DUMMY(-1, hotcpu_notifier)
DUMMY(-1, hweight32)
DUMMY(-1, hweight64)
DUMMY_STOP(0, hweight64)
DUMMY(-1, inet_ctl_sock_destroy)
DUMMY(-1, inet_diag_dump_icsk)
DUMMY(-1, inet_diag_dump_one_icsk)
@ -291,17 +312,11 @@ DUMMY(-1, is_a_nulls)
DUMMY(-1, is_multicast_ether_addr)
DUMMY(-1, is_valid_ether_addr)
DUMMY(-1, is_vlan_dev)
DUMMY(-1, jiffies_delta_to_clock_t)
DUMMY(-1, jiffies_to_clock_t)
DUMMY(-1, jiffies_to_msecs)
DUMMY(-1, jiffies_to_usecs)
DUMMY(-1, kernel_sendmsg)
DUMMY(-1, kmem_cache_destroy)
DUMMY(-1, kobject_put)
DUMMY(-1, kobject_uevent)
DUMMY(-1, krealloc)
DUMMY(-1, kref_init)
DUMMY(-1, kref_put)
DUMMY(-1, kstrdup)
DUMMY(-1, kstrtoul)
DUMMY(-1, ktime_equal)
@ -319,7 +334,7 @@ DUMMY(-1, list_replace_rcu)
DUMMY(-1, local_softirq_pending)
DUMMY(-1, lockdep_rtnl_is_held)
DUMMY(-1, min)
DUMMY(-1, mod_delayed_work)
DUMMY_STOP(-1, mod_delayed_work)
DUMMY(-1, module_put)
DUMMY(-1, move_addr_to_kernel)
DUMMY(-1, mq_qdisc_ops)
@ -360,8 +375,11 @@ DUMMY(-1, preempt_disable)
DUMMY(-1, preempt_enable)
DUMMY(-1, prefetch)
DUMMY(-1, pr_emerg)
DUMMY(-1, prepare_to_wait)
DUMMY(-1, prepare_to_wait_exclusive)
DUMMY_SKIP(0, finish_wait)
DUMMY_SKIP(0, prepare_to_wait)
DUMMY_SKIP(0, prepare_to_wait_exclusive)
DUMMY(-1, pr_err)
DUMMY(-1, pr_info)
DUMMY(-1, pr_info_once)
@ -372,7 +390,6 @@ DUMMY(-1, put_cpu_var)
DUMMY(-1, put_cred)
DUMMY(-1, put_device)
DUMMY(-1, put_pid)
DUMMY(-1, put_unaligned_be32)
DUMMY(-1, __raise_softirq_irqoff)
DUMMY(-1, raise_softirq_irqoff)
DUMMY(-1, random32)
@ -391,10 +408,10 @@ DUMMY(-1, roundup_pow_of_two)
DUMMY(-1, rt_genid_bump)
DUMMY(-1, rtnetlink_init)
DUMMY(-1, __rtnl_unlock)
DUMMY(-1, schedule)
DUMMY(-1, schedule_delayed_work)
DUMMY(-1, schedule_timeout_interruptible)
DUMMY(-1, schedule_work)
DUMMY_STOP(-1, schedule)
DUMMY_STOP(-1, schedule_delayed_work)
DUMMY_STOP(-1, schedule_timeout_interruptible)
DUMMY_STOP(-1, schedule_work)
DUMMY(-1, scm_destroy)
DUMMY(-1, scm_recv)
DUMMY(-1, scm_send)
@ -418,14 +435,12 @@ DUMMY(-1, security_socket_getpeersec_stream)
DUMMY(-1, security_sock_graft)
DUMMY(-1, send_sigurg)
DUMMY(-1, send_sig)
DUMMY(-1, __set_bit)
DUMMY(-1, set_bit)
DUMMY_STOP(-1, set_bit)
DUMMY(-1, __set_current_state)
DUMMY(-1, set_current_state)
DUMMY(-1, set_fs)
DUMMY(-1, sg_mark_end)
DUMMY(-1, sg_set_buf)
DUMMY(-1, sg_set_page)
DUMMY_STOP(-1, sg_mark_end)
DUMMY_STOP(-1, sg_set_buf)
DUMMY_STOP(-1, sg_set_page)
DUMMY(-1, sha_transform)
DUMMY(-1, si_meminfo)
DUMMY(-1, S_ISSOCK)
@ -476,14 +491,13 @@ DUMMY(-1, test_and_set_bit)
DUMMY(-1, test_bit)
DUMMY(-1, textsearch_find)
DUMMY(-1, __this_cpu_read)
DUMMY(-1, trace_napi_poll)
DUMMY(-1, trace_net_dev_queue)
DUMMY(-1, trace_netif_rx)
DUMMY(-1, trace_skb_copy_datagram_iovec)
DUMMY(-1, trace_sock_exceed_buf_limit)
DUMMY(-1, trace_sock_rcvqueue_full)
DUMMY(-1, trace_udp_fail_queue_rcv_skb)
DUMMY(-1, try_module_get)
DUMMY_SKIP(-1, trace_napi_poll)
DUMMY_SKIP(-1, trace_net_dev_queue)
DUMMY_SKIP(-1, trace_netif_rx)
DUMMY_SKIP(-1, trace_skb_copy_datagram_iovec)
DUMMY_SKIP(-1, trace_sock_exceed_buf_limit)
DUMMY_SKIP(-1, trace_sock_rcvqueue_full)
DUMMY_SKIP(-1, trace_udp_fail_queue_rcv_skb)
DUMMY(-1, tsk_restore_flags)
DUMMY(-1, u64_stats_fetch_begin_bh)
DUMMY(-1, u64_stats_fetch_retry_bh)
@ -491,7 +505,6 @@ DUMMY(-1, u64_stats_update_begin)
DUMMY(-1, u64_stats_update_end)
DUMMY(-1, udplite4_register)
DUMMY(-1, uid_eq)
DUMMY(-1, vfree)
DUMMY(-1, virt_to_page)
DUMMY(-1, vlan_do_receive)
DUMMY(-1, __vlan_put_tag)
@ -511,6 +524,160 @@ DUMMY(-1, xfrm4_udp_encap_rcv)
DUMMY(-1, xfrm_sk_free_policy)
DUMMY(-1, xfrm_user_policy)
DUMMY(-1, yield)
DUMMY(-1, __xchg)
} /* extern "C" */
DUMMY(0, __inet_twsk_schedule)
// DUMMY_RET(0xdeadbeef, __netlink_kernel_create) /* needs to be != 0, otherwise FIB will nag */
// DUMMY(0, __nlmsg_put)
DUMMY(0, __skb_flow_dissect)
DUMMY(0, __skb_get_hash)
DUMMY(0, __skb_get_poff)
DUMMY(0, __sock_tx_timestamp)
DUMMY(0, __this_cpu_write)
DUMMY(0, __vlan_get_protocol)
DUMMY(0, __vlan_hwaccel_push_inside)
DUMMY(0, __vlan_hwaccel_put_tag)
DUMMY(0, __vlan_insert_tag)
DUMMY(0, bpf_tell_extensions)
DUMMY_STOP(0, cancel_work_sync)
DUMMY_STOP(0, copy_from_iter_nocache)
// DUMMY(0, core_netlink_proto_init)
// DUMMY(0, csum_and_copy_from_iter)
// DUMMY_STOP(0, csum_and_copy_to_iter)
DUMMY(0, csum_ipv6_magic)
DUMMY(0, csum_replace4)
DUMMY(0, file_ns_capable)
DUMMY(0, find_first_bit)
DUMMY(0, find_next_bit)
DUMMY(0, flow_keys_buf_dissector)
DUMMY(0, fnhe_genid)
DUMMY(0, gfpflags_allow_blocking)
DUMMY(0, hlist_add_behind_rcu)
DUMMY(0, hlist_replace_rcu)
DUMMY(0, hrtimer_cancel)
DUMMY(0, hrtimer_init)
DUMMY(0, hrtimer_start)
DUMMY(0, icmp6_hdr)
DUMMY(0, inet_twsk_deschedule_put)
DUMMY(0, inet_twsk_free)
DUMMY_STOP(0, iov_iter_advance)
DUMMY_STOP(0, iov_iter_get_pages)
DUMMY(0, ip_tunnel_core_init)
DUMMY(0, iptunnel_metadata_reply)
DUMMY(0, ipv6_hdr)
DUMMY(0, ipv6_sk_rxinfo)
DUMMY(0, is_vmalloc_addr)
DUMMY(0, kstrtou8)
DUMMY(0, kvfree)
/* only relevant when CONFIG_NET_L3_MASTER_DEV set */
DUMMY_RET(0, l3mdev_fib_oif_rcu)
DUMMY_RET(0, l3mdev_fib_table) /* 0 is valid if !CONFIG_IP_MULTIPLE_TABLES */
DUMMY_RET(0, l3mdev_fib_table_by_index)
DUMMY_RET(0, l3mdev_get_rtable)
DUMMY_RET(0, l3mdev_get_saddr)
DUMMY_RET(0, l3mdev_master_ifindex)
DUMMY_RET(0, l3mdev_master_ifindex_rcu)
DUMMY(0, local_clock)
/* only relevant when CONFIG_LWTUNNEL set */
DUMMY(0, lwt_tun_info)
DUMMY(0, lwtstate_free)
DUMMY(0, lwtstate_get)
DUMMY_RET(0, lwtstate_put) /* no return value */
DUMMY_RET(0, lwtunnel_cmp_encap)
DUMMY(0, lwtunnel_fill_encap)
DUMMY(0, lwtunnel_get_encap_size)
DUMMY(0, lwtunnel_input_redirect)
DUMMY(0, lwtunnel_output_redirect)
DUMMY(0, make_kgid)
DUMMY(0, mod_timer_pending)
DUMMY(0, mod_timer_pinned)
DUMMY(0, netif_index_is_l3_master)
// DUMMY(0, netlink_kernel_release)
// DUMMY(0, netlink_unicast)
DUMMY(0, netpoll_poll_disable)
DUMMY(0, netpoll_poll_enable)
DUMMY(0, nf_hook_ingress_init)
DUMMY(0, nosteal_pipe_buf_ops)
DUMMY(0, ns_to_ktime)
DUMMY(0, page_is_pfmemalloc)
DUMMY(0, page_private)
DUMMY(0, percpu_counter_sum)
DUMMY(0, pr_warn_once)
DUMMY(0, prandom_seed)
DUMMY(0, prandom_u32_max)
DUMMY(0, put_group_info)
DUMMY_SHOW(0, queue_delayed_work)
DUMMY(0, raw_seqcount_begin)
DUMMY(0, read_seqcount_retry)
DUMMY(0, reciprocal_scale)
DUMMY(0, round_down)
DUMMY(0, rt_genid_bump_ipv4)
DUMMY(0, rt_genid_ipv4)
DUMMY(0, rtmsg_ifinfo_build_skb)
DUMMY(0, rtmsg_ifinfo_send)
DUMMY_SKIP(0, sched_annotate_sleep)
DUMMY(0, set_page_private)
DUMMY(0, sk_attach_bpf)
DUMMY(0, sk_busy_loop)
DUMMY(0, sk_can_busy_loop)
DUMMY(0, sk_filter_charge)
DUMMY(0, sk_filter_uncharge)
DUMMY(0, sk_mark_napi_id)
DUMMY(0, skb_vlan_tag_get)
DUMMY(0, skb_vlan_tag_get_id)
DUMMY(0, skb_vlan_tag_present)
DUMMY(0, skb_vlan_tagged)
DUMMY(0, smp_mb__after_atomic)
DUMMY(0, sock_diag_broadcast_destroy)
DUMMY(0, sock_diag_has_destroy_listeners)
/* only relevant when CONFIG_NET_SWITCHDEV was set */
DUMMY_RET(0, switchdev_fib_ipv4_abort) /* actually void, no return value */
DUMMY_RET(0, switchdev_fib_ipv4_add)
DUMMY_RET(0, switchdev_fib_ipv4_del)
DUMMY(0, sysctl_tcp_recovery)
DUMMY(0, sysfs_create_link)
DUMMY(0, sysfs_remove_link)
DUMMY(0, tcp_fastopen_init_key_once)
DUMMY(0, tcp_rack_advance)
DUMMY(0, tcp_rack_mark_lost)
DUMMY(0, tcp_try_fastopen)
DUMMY(0, tcpv4_offload_init)
DUMMY(0, this_cpu_ksoftirqd)
DUMMY_SKIP(0, trace_fib_table_lookup)
DUMMY_SKIP(0, trace_fib_table_lookup_nh)
DUMMY_SKIP(0, trace_fib_validate_source)
DUMMY_SKIP(0, trace_napi_gro_frags_entry)
DUMMY_SKIP(0, trace_napi_gro_receive_entry)
DUMMY_SKIP(0, trace_net_dev_start_xmit)
DUMMY_SKIP(0, trace_netif_receive_skb_entry)
DUMMY_SKIP(0, trace_netif_rx_entry)
DUMMY_SKIP(0, trace_netif_rx_ni_entry)
DUMMY(0, u64_stats_fetch_begin_irq)
DUMMY(0, u64_stats_fetch_retry_irq)
DUMMY(0, u64_stats_init)
DUMMY(0, udpv4_offload_init)
DUMMY(0, vlan_features_check)
DUMMY(0, vlan_hw_offload_capable)
DUMMY(0, vlan_set_encap_proto)
DUMMY(0, wait_woken)
DUMMY_STOP(0, work_pending)
DUMMY(0, __module_get)
DUMMY_RET(0, peernet2id)
DUMMY(0, ktime_get_ns)
DUMMY(0, ipv6_get_dsfield)
DUMMY_SKIP(0, spin_lock_init)
DUMMY_SKIP(0, spin_lock_nested)
DUMMY_SKIP(0, spin_lock)
DUMMY_SKIP(0, spin_unlock)
DUMMY_SKIP(0, spin_lock_bh)
DUMMY_SKIP(0, spin_unlock_bh)
DUMMY(0, peernet_has_id)
} /* extern "C" */

View File

@ -11,8 +11,10 @@
* under the terms of the GNU General Public License version 2.
*/
/* local includes */
#include <lx_emul.h>
int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
{
printk("%s called (from %p) not implemented", __func__, __builtin_return_address(0));

View File

@ -1,20 +0,0 @@
/*
* \brief Global environment
* \author Stefan Kalkowski
* \date 2013-05-23
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include "env.h"
Genode::Signal_receiver* Net::Env::receiver()
{
static Genode::Signal_receiver receiver;
return &receiver;
}

View File

@ -1,30 +0,0 @@
/*
* \brief Proxy-ARP environment
* \author Stefan Kalkowski
* \date 2013-05-24
*
* A database containing all clients sorted by IP and MAC addresses.
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _SRC__SERVER__NIC_BRIDGE__ENV_H_
#define _SRC__SERVER__NIC_BRIDGE__ENV_H_
#include <base/signal.h>
namespace Net {
struct Env;
}
struct Net::Env
{
static Genode::Signal_receiver* receiver();
};
#endif /* _SRC__SERVER__NIC_BRIDGE__ENV_H_ */

View File

@ -1,22 +0,0 @@
/**
* \brief IP stack initialization
* \author Sebastian Sumpf
* \date 2013-09-26
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__INIT_H_
#define _INCLUDE__INIT_H_
#ifdef __cplusplus
extern "C"
#endif
int lxip_init(char *address_config);
#endif

View File

@ -0,0 +1,5 @@
#define __UAPI_DEF_IN_ADDR 1
#define __UAPI_DEF_SOCKADDR_IN 1
#include <uapi/linux/in.h>
#undef __UAPI_DEF_SOCKADDR_IN
#undef __UAPI_DEF_IN_ADDR

View File

@ -0,0 +1,5 @@
#define __UAPI_DEF_IPPROTO_V6 1
#define __UAPI_DEF_IN6_ADDR 1
#include <uapi/linux/in6.h>
#undef __UAPI_DEF_IN6_ADDR
#undef __UAPI_DEF_IPPROTO_V6

File diff suppressed because it is too large Load Diff

View File

@ -1,74 +0,0 @@
/*
* \brief Signal driven network handler
* \author Stefan Kalkowski
* \auhtor Sebastian Sumpf
* \date 2013-09-24
*/
/*
* Copyright (C) 2010-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _PACKET_HANDLER_H_
#define _PACKET_HANDLER_H_
/* Genode */
#include <nic_session/connection.h>
namespace Net {
class Packet_handler;
using Nic::Packet_stream_sink;
using Nic::Packet_stream_source;
using Nic::Packet_descriptor;
}
/**
* Generic packet handler used as base for NIC and client packet handlers.
*/
class Net::Packet_handler
{
protected:
/**
* submit queue not empty anymore
*/
void _packet_avail(unsigned);
/**
* acknoledgement queue not full anymore
*/
void _ready_to_ack(unsigned);
/**
* acknoledgement queue not empty anymore
*/
void _ack_avail(unsigned);
/**
* submit queue not full anymore
*
* TODO: by now, we just drop packets that cannot be transferred
* to the other side, that's why we ignore this signal.
*/
void _ready_to_submit(unsigned) { }
Genode::Signal_dispatcher<Packet_handler> _sink_ack;
Genode::Signal_dispatcher<Packet_handler> _sink_submit;
Genode::Signal_dispatcher<Packet_handler> _source_ack;
Genode::Signal_dispatcher<Packet_handler> _source_submit;
public:
Packet_handler();
virtual Packet_stream_sink< ::Nic::Session::Policy> * sink() = 0;
virtual Packet_stream_source< ::Nic::Session::Policy> * source() = 0;
};
#endif /* _PACKET_HANDLER_H_ */

View File

@ -1,87 +0,0 @@
/**
* \brief IP stack initialization
* \author Sebastian Sumpf
* \date 2013-08-26
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <linux/inetdevice.h>
#include <net/tcp.h>
#include <init.h>
/*
* Header declarations and tuning
*/
struct net init_net;
unsigned long *sysctl_local_reserved_ports;
struct pernet_operations loopback_net_ops;
/**
* nr_free_buffer_pages - count number of pages beyond high watermark
*
* nr_free_buffer_pages() counts the number of pages which are beyond the
* high
* watermark within ZONE_DMA and ZONE_NORMAL.
*/
unsigned long nr_free_buffer_pages(void)
{
return 1000;
}
/*
* Declare stuff used
*/
int __ip_auto_config_setup(char *addrs);
void core_sock_init(void);
void core_netlink_proto_init(void);
void subsys_net_dev_init(void);
void fs_inet_init(void);
void module_driver_init(void);
void module_cubictcp_register(void);
void late_ip_auto_config(void);
void late_tcp_congestion_default(void);
/**
* Initialize sub-systems
*/
int lxip_init(char *address_config)
{
/* init data */
INIT_LIST_HEAD(&init_net.dev_base_head);
/* call __setup stuff */
__ip_auto_config_setup(address_config);
core_sock_init();
core_netlink_proto_init();
/* sub-systems */
subsys_net_dev_init();
fs_inet_init();
/* enable local accepts */
IPV4_DEVCONF_ALL(&init_net, ACCEPT_LOCAL) = 0x1;
/* congestion control */
module_cubictcp_register();
/* driver */
module_driver_init();
/* late */
late_tcp_congestion_default();
/* dhcp or static configuration */
late_ip_auto_config();
return 1;
}

View File

@ -0,0 +1,30 @@
/*
* \brief Lx env
* \author Josef Soentgen
* \date 2014-10-17
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _LX_H_
#define _LX_H_
#include <base/signal.h>
namespace Lx {
void nic_client_init(Genode::Signal_receiver &);
void timer_init(Genode::Signal_receiver &);
void event_init(Genode::Signal_receiver &);
void timer_update_jiffies();
}
extern "C" int lxip_init(char const *address_config);
#endif /* _LX_H_ */

View File

@ -1,77 +1,51 @@
/**
* \brief Linux emulation code
* \author Sebastian Sumpf
* \author Josef Soentgen
* \date 2013-08-30
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
* Copyright (C) 2013-2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Linux includes */
#include <linux/inetdevice.h>
#include <linux/net.h>
#include <linux/netdevice.h>
#include <net/ip_fib.h>
#include <uapi/linux/rtnetlink.h>
#include <net/sock.h>
#include <net/route.h>
#include <net/ip_fib.h>
#include <net/tcp.h>
#include <net/tcp_states.h>
/********************
** linux/slab.h **
********************/
/***********************
** linux/genetlink.h **
***********************/
struct kmem_cache
/* needed by af_netlink.c */
atomic_t genl_sk_destructing_cnt;
wait_queue_head_t genl_sk_destructing_waitq;
/****************************
** asm-generic/atomic64.h **
****************************/
long long atomic64_read(const atomic64_t *v)
{
const char *name; /* cache name */
unsigned size; /* object size */
};
struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align,
unsigned long falgs, void (*ctor)(void *))
{
lx_log(DEBUG_SLAB, "\"%s\" obj_size=%zd", name, size);
struct kmem_cache *cache;
if (!name) {
pr_info("kmem_cache name required\n");
return 0;
}
cache = (struct kmem_cache *)kmalloc(sizeof(*cache), 0);
if (!cache) {
pr_crit("No memory for slab cache\n");
return 0;
}
cache->name = name;
cache->size = size;
return cache;
return v->counter;
}
void *kmem_cache_alloc_node(struct kmem_cache *cache, gfp_t flags, int node)
void atomic64_set(atomic64_t *v, long long i)
{
lx_log(DEBUG_SLAB, "\"%s\" alloc obj_size=%u", cache->name,cache->size);
return kmalloc(cache->size, 0);
}
void *kmem_cache_alloc(struct kmem_cache *cache, gfp_t flags)
{
lx_log(DEBUG_SLAB, "\"%s\" alloc obj_size=%u", cache->name,cache->size);
return kmalloc(cache->size, 0);
}
void kmem_cache_free(struct kmem_cache *cache, void *objp)
{
lx_log(DEBUG_SLAB, "\"%s\" (%p)", cache->name, objp);
kfree(objp);
v->counter = i;
}
@ -134,6 +108,7 @@ u32 hash_32(u32 val, unsigned int bits)
return hash;
}
/******************
** linux/dcache **
******************/
@ -147,6 +122,7 @@ unsigned int full_name_hash(const unsigned char *name, unsigned int len)
return hash;
}
/******************************
* net/core/net/namespace.h **
******************************/
@ -196,16 +172,6 @@ struct iphdr *ip_hdr(const struct sk_buff *skb)
}
/***********************
** linux/netdevice.h **
***********************/
struct netdev_queue *netdev_pick_tx(struct net_device *dev, struct sk_buff *skb)
{
return netdev_get_tx_queue(dev, 0);
}
/*******************************
** asm-generic/bitops/find.h **
*******************************/
@ -249,8 +215,10 @@ int get_order(unsigned long size)
** linux/jiffies.h **
*********************/
long time_after_eq(long a, long b) { return (a - b) >= 0; }
long time_after(long a, long b) { return (b - a) < 0; }
clock_t jiffies_to_clock_t(unsigned long j)
{
return j / HZ; /* XXX not sure if this is enough */
}
/*********************
@ -356,14 +324,211 @@ __wsum csum_block_add(__wsum csum, __wsum csum2, int offset)
}
/**
* Misc
__wsum csum_block_add_ext(__wsum csum, __wsum csum2, int offset, int len)
{
return csum_block_add(csum, csum2, offset);
}
/***************************
** Linux socket function **
***************************/
static const struct net_proto_family *net_families[NPROTO];
int sock_register(const struct net_proto_family *ops)
{
if (ops->family >= NPROTO) {
printk("protocol %d >= NPROTO (%d)\n", ops->family, NPROTO);
return -ENOBUFS;
}
net_families[ops->family] = ops;
pr_info("NET: Registered protocol family %d\n", ops->family);
return 0;
}
struct socket *sock_alloc(void)
{
struct socket *sock = (struct socket *)kzalloc(sizeof(struct socket), 0);
/*
* Linux normally allocates the socket_wq when calling
* sock_alloc_inode() while we do it here hoping for the best.
*/
sock->wq = (struct socket_wq*)kzalloc(sizeof(*sock->wq), 0);
if (!sock->wq) {
kfree(sock);
return NULL;
}
return sock;
}
int sock_create_lite(int family, int type, int protocol, struct socket **res)
{
struct socket *sock = sock_alloc();
if (!sock)
return -ENOMEM;
sock->type = type;
*res = sock;
return 0;
}
int sock_create_kern(struct net *net, int family, int type, int proto,
struct socket **res)
{
struct socket *sock;
const struct net_proto_family *pf;
int err;
if (family < 0 || family > NPROTO)
return -EAFNOSUPPORT;
if (type < 0 || type > SOCK_MAX)
return -EINVAL;
pf = net_families[family];
if (!pf) {
printk("No protocol found for family %d\n", family);
return -ENOPROTOOPT;
}
sock = sock_alloc();
if (!sock) {
printk("Could not allocate socket\n");
return -ENFILE;
}
sock->type = type;
err = pf->create(&init_net, sock, proto, 1);
if (err) {
kfree(sock);
return err;
}
*res = sock;
return 0;
}
static void sock_init(void)
{
skb_init();
}
core_initcall(sock_init);
/*************************
** Lxip initialization **
*************************/
/*
* Header declarations and tuning
*/
struct net init_net;
unsigned long *sysctl_local_reserved_ports;
struct pernet_operations loopback_net_ops;
/**
* nr_free_buffer_pages - count number of pages beyond high watermark
*
* nr_free_buffer_pages() counts the number of pages which are beyond the
* high
* watermark within ZONE_DMA and ZONE_NORMAL.
*/
unsigned long nr_free_buffer_pages(void)
{
return 1000;
}
/*
* Declare stuff used
*/
int __ip_auto_config_setup(char *addrs);
void core_sock_init(void);
void core_netlink_proto_init(void);
void subsys_net_dev_init(void);
void fs_inet_init(void);
void module_driver_init(void);
void module_cubictcp_register(void);
void late_ip_auto_config(void);
void late_tcp_congestion_default(void);
/**
* Initialize sub-systems
*/
int lxip_init(char const *address_config)
{
/* init data */
INIT_LIST_HEAD(&init_net.dev_base_head);
/* call __setup stuff */
__ip_auto_config_setup((char *)address_config);
core_sock_init();
core_netlink_proto_init();
/* sub-systems */
subsys_net_dev_init();
fs_inet_init();
/* enable local accepts */
IPV4_DEVCONF_ALL(&init_net, ACCEPT_LOCAL) = 0x1;
/* congestion control */
module_cubictcp_register();
/* driver */
module_driver_init();
/* late */
late_tcp_congestion_default();
/* dhcp or static configuration */
late_ip_auto_config();
return 0;
}
/******************
** Lxip private **
******************/
void set_sock_wait(struct socket *sock, unsigned long ptr)
{
sock->sk->sk_wq = (struct socket_wq *)ptr;
}
int socket_check_state(struct socket *socket)
{
if (socket->sk->sk_state == TCP_CLOSE_WAIT)
return -EINTR;
return 0;
}
void log_sock(struct socket *socket)
{
printk("\nNEW socket %p sk %p fsk %x &sk %p &fsk %p\n\n",
socket, socket->sk, socket->flags, &socket->sk, &socket->flags);
}

View File

@ -5,401 +5,87 @@
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
* Copyright (C) 2013-2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/allocator_avl.h>
#include <base/object_pool.h>
#include <base/sleep.h>
#include <base/snprintf.h>
#include <dataspace/client.h>
#include <region_map/client.h>
#include <timer_session/connection.h>
#include <trace/timestamp.h>
#include <lx/extern_c_begin.h>
/* local includes */
#include <lx_emul.h>
#include <lx/extern_c_end.h>
#include <env.h>
#include <lx.h>
/*
* VM-area to reserve for back-end allocator
*/
enum { VM_RESERVATION = 24 * 1024 * 1024 };
/*********************************
** Lx::Backend_alloc interface **
*********************************/
/*
* TODO: fine tune these
*/
unsigned long totalram_pages = VM_RESERVATION / PAGE_SIZE;
unsigned long num_physpages = totalram_pages;
#include <lx_kit/backend_alloc.h>
namespace Genode {
template <unsigned VM_SIZE> class Slab_backend_alloc;
typedef Slab_backend_alloc<VM_RESERVATION> Backend_alloc;
class Slab_alloc;
struct Memory_object_base : Genode::Object_pool<Memory_object_base>::Entry
{
Memory_object_base(Genode::Ram_dataspace_capability cap)
: Genode::Object_pool<Memory_object_base>::Entry(cap) {}
void free() { Genode::env()->ram_session()->free(ram_cap()); }
Genode::Ram_dataspace_capability ram_cap()
{
using namespace Genode;
return reinterpret_cap_cast<Ram_dataspace>(cap());
}
};
static Genode::Object_pool<Memory_object_base> memory_pool;
Genode::Ram_dataspace_capability
Lx::backend_alloc(Genode::addr_t size, Genode::Cache_attribute cached)
{
using namespace Genode;
Genode::Ram_dataspace_capability cap = env()->ram_session()->alloc(size);
Memory_object_base *o = new (env()->heap()) Memory_object_base(cap);
memory_pool.insert(o);
return cap;
}
/**
* Back-end allocator for Genode's slab allocator
*/
template <unsigned VM_SIZE>
class Genode::Slab_backend_alloc : public Genode::Allocator,
public Genode::Rm_connection,
public Genode::Region_map_client
void Lx::backend_free(Genode::Ram_dataspace_capability cap)
{
private:
using namespace Genode;
enum {
BLOCK_SIZE = 1024 * 1024, /* 1 MB */
ELEMENTS = VM_SIZE / BLOCK_SIZE, /* MAX number of dataspaces in VM */
};
Memory_object_base *object;
memory_pool.apply(cap, [&] (Memory_object_base *o) {
if (!o) return;
addr_t _base; /* virt. base address */
Cache_attribute _cached; /* non-/cached RAM */
Ram_dataspace_capability _ds_cap[ELEMENTS]; /* dataspaces to put in VM */
addr_t _ds_phys[ELEMENTS]; /* physical bases of dataspaces */
int _index; /* current index in ds_cap */
Allocator_avl _range; /* manage allocations */
o->free();
memory_pool.remove(o);
bool _alloc_block()
{
if (_index == ELEMENTS) {
PERR("Slab-backend exhausted!");
return false;
}
try {
_ds_cap[_index] = Genode::env()->ram_session()->alloc(BLOCK_SIZE, _cached);
/* attach at index * BLOCK_SIZE */
Region_map_client::attach_at(_ds_cap[_index], _index * BLOCK_SIZE, BLOCK_SIZE, 0);
/* lookup phys. address */
_ds_phys[_index] = Dataspace_client(_ds_cap[_index]).phys_addr();
} catch (...) { return false; }
/* return base + offset in VM area */
addr_t block_base = _base + (_index * BLOCK_SIZE);
++_index;
_range.add_range(block_base, BLOCK_SIZE);
return true;
}
public:
Slab_backend_alloc(Cache_attribute cached)
:
Region_map_client(Rm_connection::create(VM_SIZE)),
_cached(cached), _index(0), _range(env()->heap())
{
/* reserver attach us, anywere */
_base = env()->rm_session()->attach(dataspace());
}
/**
* Allocate
*/
bool alloc(size_t size, void **out_addr) override
{
bool done = _range.alloc(size, out_addr);
if (done)
return done;
done = _alloc_block();
if (!done) {
PERR("Backend allocator exhausted\n");
return false;
}
return _range.alloc(size, out_addr);
}
void free(void *addr, size_t size) override { _range.free(addr, size); }
size_t overhead(size_t size) const override { return 0; }
bool need_size_for_free() const override { return false; }
/**
* Return phys address for given virtual addr.
*/
addr_t phys_addr(addr_t addr)
{
if (addr < _base || addr >= (_base + VM_SIZE))
return ~0UL;
int index = (addr - _base) / BLOCK_SIZE;
/* physical base of dataspace */
addr_t phys = _ds_phys[index];
if (!phys)
return ~0UL;
/* add offset */
phys += (addr - _base - (index * BLOCK_SIZE));
return phys;
}
addr_t start() const { return _base; }
addr_t end() const { return _base + VM_SIZE - 1; }
};
/**
* Slab allocator using our back-end allocator
*/
class Genode::Slab_alloc : public Genode::Slab
{
private:
Genode::size_t const _object_size;
static Genode::size_t _calculate_block_size(Genode::size_t object_size)
{
Genode::size_t const block_size = 16*object_size;
return align_addr(block_size, 12);
}
public:
Slab_alloc(size_t object_size, Backend_alloc *allocator)
:
Slab(object_size, _calculate_block_size(object_size), 0, allocator),
_object_size(object_size)
{ }
inline addr_t alloc()
{
Genode::addr_t result;
return (Slab::alloc(_object_size, (void **)&result) ? result : 0);
}
void free(void *ptr) { Slab::free(ptr, _object_size); }
};
/**
* Memory interface used used for Linux emulation
*/
class Malloc
{
private:
enum {
SLAB_START_LOG2 = 3, /* 8 B */
SLAB_STOP_LOG2 = 16, /* 64 KB */
NUM_SLABS = (SLAB_STOP_LOG2 - SLAB_START_LOG2) + 1,
};
typedef Genode::addr_t addr_t;
typedef Genode::Slab_alloc Slab_alloc;
typedef Genode::Slab_backend_alloc<VM_RESERVATION> Slab_backend_alloc;
Slab_backend_alloc *_back_allocator;
Slab_alloc *_allocator[NUM_SLABS];
bool _cached; /* cached or un-cached memory */
addr_t _start; /* VM region of this allocator */
addr_t _end;
/**
* Set 'value' at 'addr'
*/
void _set_at(addr_t addr, addr_t value) { *((addr_t *)addr) = value; }
/**
* Retrieve slab index belonging to given address
*/
unsigned _slab_index(Genode::addr_t **addr)
{
using namespace Genode;
/* get index */
addr_t index = *(*addr - 1);
/*
* If index large, we use aligned memory, retrieve beginning of slab entry
* and read index from there
*/
if (index > 32) {
*addr = (addr_t *)*(*addr - 1);
index = *(*addr - 1);
}
return index;
}
public:
Malloc(Slab_backend_alloc *alloc, Genode::Cache_attribute cached)
: _back_allocator(alloc), _cached(cached), _start(alloc->start()),
_end(alloc->end())
{
/* init slab allocators */
for (unsigned i = SLAB_START_LOG2; i <= SLAB_STOP_LOG2; i++)
_allocator[i - SLAB_START_LOG2] = new (Genode::env()->heap())
Slab_alloc(1U << i, alloc);
}
/**
* Alloc in slabs
*/
void *alloc(Genode::size_t size, int align = 0, Genode::addr_t *phys = 0)
{
using namespace Genode;
/* += slab index + aligment size */
size += sizeof(addr_t) + (align > 2 ? (1 << align) : 0);
int msb = Genode::log2(size);
if (size > (1U << msb))
msb++;
if (size < (1U << SLAB_START_LOG2))
msb = SLAB_STOP_LOG2;
if (msb > SLAB_STOP_LOG2) {
PERR("Slab too large %u requested %zu cached %d", 1U << msb, size, _cached);
return 0;
}
addr_t addr = _allocator[msb - SLAB_START_LOG2]->alloc();
if (!addr) {
PERR("Failed to get slab for %u", 1 << msb);
return 0;
}
_set_at(addr, msb - SLAB_START_LOG2);
addr += sizeof(addr_t);
if (align > 2) {
/* save */
addr_t ptr = addr;
addr_t align_val = (1U << align);
addr_t align_mask = align_val - 1;
/* align */
addr = (addr + align_val) & ~align_mask;
/* write start address before aligned address */
_set_at(addr - sizeof(addr_t), ptr);
}
if (phys)
*phys = _back_allocator->phys_addr(addr);
return (addr_t *)addr;
}
void free(void const *a)
{
using namespace Genode;
addr_t *addr = (addr_t *)a;
unsigned nr = _slab_index(&addr);
_allocator[nr]->free((void *)(addr - 1));
}
size_t slab_size(void const *a)
{
using namespace Genode;
addr_t *addr =(addr_t *)a;
unsigned nr = _slab_index(&addr);
size_t size = 1 << (SLAB_START_LOG2 + nr);
size -= (addr_t)a - (addr_t)(addr - 1);
return size;
}
Genode::addr_t phys_addr(void *a)
{
return _back_allocator->phys_addr((addr_t)a);
}
/**
* Belongs given address to this allocator
*/
bool inside(addr_t const addr) const { return (addr > _start) && (addr <= _end); }
/**
* Cached memory allocator
*/
static Malloc *mem()
{
static Slab_backend_alloc _b(Genode::CACHED);
static Malloc _m(&_b, Genode::CACHED);
return &_m;
}
};
object = o; /* save for destroy */
});
destroy(env()->heap(), object);
}
/*************************************
** Memory allocation, linux/slab.h **
*************************************/
void *kmalloc(size_t size, gfp_t flags)
{
void *addr = Malloc::mem()->alloc(size);
unsigned long a = (unsigned long)addr;
if (a & 0x3)
PERR("Unaligned kmalloc %lx", a);
// PDBG("Kmalloc: [%lx-%lx) from %p", a, a + size, __builtin_return_address(0));
return addr;
}
void *kzalloc(size_t size, gfp_t flags)
{
void *addr = kmalloc(size, flags);
if (addr)
Genode::memset(addr, 0, size);
//PDBG("Kmalloc: [%lx-%lx) from %p", (unsigned)addr, (unsigned)addr + size, __builtin_return_address(0));
return addr;
}
void *kcalloc(size_t n, size_t size, gfp_t flags)
{
if (size != 0 && n > ~0UL / size)
return 0;
return kzalloc(n * size, flags);
}
void kfree(const void *p)
{
if (!p) return;
if (Malloc::mem()->inside((Genode::addr_t)p))
Malloc::mem()->free(p);
else
PWRN("%p is not within our memory range called from %p",
p, __builtin_return_address(0));
}
void *kmalloc_node_track_caller(size_t size, gfp_t flags, int node)
{
return kmalloc(size, 0);
}
void *kzalloc_node(size_t size, gfp_t flags, int node)
{
return kzalloc(size, 0);
}
size_t ksize(const void *p)
{
if (!(Malloc::mem()->inside((Genode::addr_t)p))) {
PDBG("%p not in slab allocator", p);
return 0;
}
size_t size = Malloc::mem()->slab_size(p);
return size;
}
#include <lx_emul/impl/slab.h>
void *alloc_large_system_hash(const char *tablename,
@ -427,6 +113,46 @@ void *alloc_large_system_hash(const char *tablename,
}
void *kmalloc_array(size_t n, size_t size, gfp_t flags)
{
if (size != 0 && n > SIZE_MAX / size) return NULL;
return kmalloc(n * size, flags);
}
/********************
** linux/slab.h **
********************/
void *kmem_cache_alloc_node(struct kmem_cache *cache, gfp_t flags, int node)
{
return (void*)cache->alloc();
}
void *kmem_cache_zalloc(struct kmem_cache *cache, gfp_t flags)
{
void *addr = (void*)cache->alloc();
if (addr) { memset(addr, 0, cache->size()); }
return addr;
}
/*********************
** linux/vmalloc.h **
*********************/
void *vmalloc(unsigned long size)
{
return kmalloc(size, 0);
}
void vfree(void const *addr)
{
kfree(addr);
}
/********************
** linux/string.h **
@ -454,6 +180,7 @@ char *strchr(const char *p, int ch)
return 0;
}
char *strnchr(const char *p, size_t count, int ch)
{
char c;
@ -468,6 +195,7 @@ char *strnchr(const char *p, size_t count, int ch)
return 0;
}
size_t strnlen(const char *s, size_t maxlen)
{
size_t c;
@ -478,14 +206,19 @@ size_t strnlen(const char *s, size_t maxlen)
return maxlen;
}
size_t strlen(const char *s) { return Genode::strlen(s); }
int strcmp(const char *s1, const char *s2) { return Genode::strcmp(s1, s2); }
int strncmp(const char *s1, const char *s2, size_t len) {
int strcmp(const char *s1, const char *s2) { return Genode::strcmp(s1, s2); }
int strncmp(const char *s1, const char *s2, size_t len) {
return Genode::strcmp(s1, s2, len); }
int memcmp(const void *p0, const void *p1, size_t size) {
return Genode::memcmp(p0, p1, size); }
int memcmp(const void *p0, const void *p1, size_t size) {
return Genode::memcmp(p0, p1, size); }
int snprintf(char *str, size_t size, const char *format, ...)
@ -494,9 +227,7 @@ int snprintf(char *str, size_t size, const char *format, ...)
va_start(list, format);
Genode::String_console sc(str, size);
sc.vprintf(format, list);
va_end(list);
return sc.len();
@ -516,37 +247,31 @@ size_t strlcpy(char *dest, const char *src, size_t size)
}
void *kmemdup(const void *src, size_t len, gfp_t gfp)
{
void *ptr = kmalloc(len, gfp);
Genode::memcpy(ptr, src, len);
return ptr;
}
void *genode_memcpy(void *d, const void *s, size_t n)
void *memcpy(void *d, const void *s, size_t n)
{
return Genode::memcpy(d, s, n);
}
/******************
** linux/log2.h **
******************/
unsigned long ilog2(unsigned long n) { return Genode::log2<unsigned long>(n); }
/*******************
** linux/sched.h **
*******************/
static Genode::Signal_receiver *_sig_rec;
void Lx::event_init(Genode::Signal_receiver &sig_rec)
{
_sig_rec = &sig_rec;
}
struct Timeout : Genode::Signal_dispatcher<Timeout>
{
void handle(unsigned) { update_jiffies(); }
Timeout(Timer::Session_client &timer, signed long msec)
: Signal_dispatcher<Timeout>(*Net::Env::receiver(), *this, &Timeout::handle)
: Signal_dispatcher<Timeout>(*_sig_rec, *this, &Timeout::handle)
{
if (msec > 0) {
timer.sigh(*this);
@ -562,7 +287,7 @@ static void __wait_event(signed long timeout)
Timeout to(timer, timeout);
/* dispatch signal */
Genode::Signal s = Net::Env::receiver()->wait_for_signal();
Genode::Signal s = _sig_rec->wait_for_signal();
static_cast<Genode::Signal_dispatcher_base *>(s.context())->dispatch(s.num());
}
@ -581,6 +306,7 @@ signed long schedule_timeout(signed long timeout)
return timeout < 0 ? 0 : timeout;
}
void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
{
__wait_event(0);
@ -596,6 +322,7 @@ unsigned long get_seconds(void)
return jiffies / HZ;
}
/*****************
** linux/gfp.h **
*****************/
@ -625,11 +352,12 @@ class Avl_page : public Genode::Avl_node<Avl_page>
_page->addr = (void *)_addr;
atomic_set(&_page->_count, 1);
lx_log(DEBUG_SLAB, "alloc page: %p addr: %lx-%lx", _page, _addr, _addr + size);
lx_log(DEBUG_SLAB, "alloc page: %p addr: %lx-%lx", _page, _addr, _addr + _size);
}
virtual ~Avl_page()
{
lx_log(DEBUG_SLAB, "free page: %p addr: %lx-%lx", _page, _addr, _addr + _size);
kfree((void *)_addr);
kfree((void *)_page);
}
@ -640,20 +368,22 @@ class Avl_page : public Genode::Avl_node<Avl_page>
{
return c->_addr > _addr;
}
Avl_page *find_by_address(Genode::addr_t addr)
{
if (addr >= _addr && addr < _addr + _size)
return this;
bool side = addr > _addr;
Avl_page *c = Avl_node<Avl_page>::child(side);
return c ? c->find_by_address(addr) : 0;
}
};
static Genode::Avl_tree<Avl_page> tree;
struct page *alloc_pages(gfp_t gfp_mask, unsigned int order)
{
Avl_page *p;
@ -666,6 +396,25 @@ struct page *alloc_pages(gfp_t gfp_mask, unsigned int order)
}
void *__alloc_page_frag(struct page_frag_cache *nc,
unsigned int fragsz, gfp_t gfp_mask)
{
struct page *page = alloc_pages(gfp_mask, fragsz / PAGE_SIZE);
if (!page) return nullptr;
return page->addr;
}
void __free_page_frag(void *addr)
{
Avl_page *p = tree.first()->find_by_address((Genode::addr_t)addr);
tree.remove(p);
destroy(Genode::env()->heap(), p);
}
/****************
** linux/mm.h **
****************/
@ -719,3 +468,165 @@ extern "C" void lx_trace_event(char const *fmt, ...)
create_event(fmt, list);
va_end(list);
}
/*****************
** linux/uio.h **
*****************/
size_t copy_from_iter(void *addr, size_t bytes, struct iov_iter *i)
{
if (bytes > i->count)
bytes = i->count;
if (bytes == 0)
return 0;
char *kdata = reinterpret_cast<char*>(addr);
struct iovec const *iov = i->iov;
size_t len = bytes;
while (len > 0) {
if (iov->iov_len) {
size_t copy_len = (size_t)len < iov->iov_len ? len : iov->iov_len;
Genode::memcpy(kdata, iov->iov_base, copy_len);
len -= copy_len;
kdata += copy_len;
i->count -= copy_len; /* XXX the vanilla macro does that */
}
iov++;
}
return bytes;
}
size_t copy_to_iter(void *addr, size_t bytes, struct iov_iter *i)
{
if (bytes > i->count)
bytes = i->count;
if (bytes == 0)
return 0;
char *kdata = reinterpret_cast<char*>(addr);
struct iovec const *iov = i->iov;
size_t len = bytes;
while (len > 0) {
if (iov->iov_len) {
size_t copy_len = (size_t)len < iov->iov_len ? len : iov->iov_len;
Genode::memcpy(iov->iov_base, kdata, copy_len);
len -= copy_len;
kdata += copy_len;
i->count -= copy_len; /* XXX the vanilla macro does that */
}
iov++;
}
return bytes;
}
size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes,
struct iov_iter *i)
{
return copy_to_iter(reinterpret_cast<unsigned char*>(page->addr) + offset, bytes, i);
}
size_t copy_page_from_iter(struct page *page, size_t offset, size_t bytes,
struct iov_iter *i)
{
return copy_from_iter(reinterpret_cast<unsigned char*>(page->addr) + offset, bytes, i);
}
size_t csum_and_copy_from_iter(void *addr, size_t bytes, __wsum *csum, struct iov_iter *i)
{
if (bytes > i->count)
bytes = i->count;
if (bytes == 0)
return 0;
char *kdata = reinterpret_cast<char*>(addr);
struct iovec const *iov = i->iov;
__wsum sum = *csum;
size_t len = bytes;
while (len > 0) {
if (iov->iov_len) {
size_t copy_len = (size_t)len < iov->iov_len ? len : iov->iov_len;
int err = 0;
__wsum next = csum_and_copy_from_user(iov->iov_base, kdata, copy_len, 0, &err);
if (err) {
PERR("%s: err: %d - sleeping", __func__, err);
Genode::sleep_forever();
}
sum = csum_block_add(sum, next, bytes-len);
len -= copy_len;
kdata += copy_len;
i->count -= copy_len; /* XXX the vanilla macro does that */
}
iov++;
}
*csum = sum;
return bytes;
}
size_t csum_and_copy_to_iter(void *addr, size_t bytes, __wsum *csum, struct iov_iter *i)
{
if (bytes > i->count)
bytes = i->count;
if (bytes == 0)
return 0;
char *kdata = reinterpret_cast<char*>(addr);
struct iovec const *iov = i->iov;
__wsum sum = *csum;
size_t len = bytes;
while (len > 0) {
if (iov->iov_len) {
size_t copy_len = (size_t)len < iov->iov_len ? len : iov->iov_len;
int err = 0;
__wsum next = csum_and_copy_to_user(kdata, iov->iov_base, copy_len, 0, &err);
if (err) {
PERR("%s: err: %d - sleeping", __func__, err);
Genode::sleep_forever();
}
sum = csum_block_add(sum, next, bytes-len);
len -= copy_len;
kdata += copy_len;
i->count -= copy_len; /* XXX the vanilla macro does that */
}
iov++;
}
*csum = sum;
return bytes;
}
/******************
** linux/wait.h **
******************/
void __wake_up(wait_queue_head_t *q, bool all) { }

View File

@ -1,38 +1,103 @@
/**
* \brief Linux emulation code
* \author Sebastian Sumpf
* \author Josef Soentgen
* \date 2013-08-28
*/
/*
* Copyright (C) 2013-2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/printf.h>
#include <nic/packet_allocator.h>
#include <nic_session/connection.h>
#include <env.h>
/* local includes */
#include <lx.h>
#include <nic.h>
#include <packet_handler.h>
enum {
MAC_LEN = 17,
ETH_ALEN = 6,
};
namespace Net {
class Nic;
}
class Net::Nic : public Net::Packet_handler
class Nic_client
{
private:
enum {
PACKET_SIZE = ::Nic::Packet_allocator::DEFAULT_PACKET_SIZE,
BUF_SIZE = ::Nic::Session::QUEUE_SIZE * PACKET_SIZE,
PACKET_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE,
BUF_SIZE = Nic::Session::QUEUE_SIZE * PACKET_SIZE,
};
::Nic::Packet_allocator _tx_block_alloc;
::Nic::Connection _nic;
Nic::Packet_allocator _tx_block_alloc;
Nic::Connection _nic;
Genode::Signal_dispatcher<Nic_client> _sink_ack;
Genode::Signal_dispatcher<Nic_client> _sink_submit;
Genode::Signal_dispatcher<Nic_client> _source_ack;
Genode::Signal_dispatcher<Nic_client> _source_submit;
/**
* submit queue not empty anymore
*/
void _packet_avail(unsigned)
{
enum { MAX_PACKETS = 20 };
int count = 0;
while (_nic.rx()->packet_avail() &&
_nic.rx()->ready_to_ack() &&
count++ < MAX_PACKETS)
{
Nic::Packet_descriptor p = _nic.rx()->get_packet();
net_driver_rx(_nic.rx()->packet_content(p), p.size());
_nic.rx()->acknowledge_packet(p);
}
if (_nic.rx()->packet_avail())
Genode::Signal_transmitter(_sink_submit).submit();
}
/**
* acknoledgement queue not full anymore
*/
void _ready_to_ack(unsigned num)
{
_packet_avail(num);
}
/**
* acknoledgement queue not empty anymore
*/
void _ack_avail(unsigned)
{
while (_nic.tx()->ack_avail()) {
Nic::Packet_descriptor p = _nic.tx()->get_acked_packet();
_nic.tx()->release_packet(p);
}
}
/**
* submit queue not full anymore
*
* TODO: by now, we just drop packets that cannot be transferred
* to the other side, that's why we ignore this signal.
*/
void _ready_to_submit(unsigned) { }
public:
Nic()
: _tx_block_alloc(Genode::env()->heap()),
_nic(&_tx_block_alloc, BUF_SIZE, BUF_SIZE)
Nic_client(Genode::Signal_receiver &sig_rec)
:
_tx_block_alloc(Genode::env()->heap()),
_nic(&_tx_block_alloc, BUF_SIZE, BUF_SIZE),
_sink_ack(sig_rec, *this, &Nic_client::_ready_to_ack),
_sink_submit(sig_rec, *this, &Nic_client::_packet_avail),
_source_ack(sig_rec, *this, &Nic_client::_ack_avail),
_source_submit(sig_rec, *this, &Nic_client::_ready_to_submit)
{
_nic.rx_channel()->sigh_ready_to_ack(_sink_ack);
_nic.rx_channel()->sigh_packet_avail(_sink_submit);
@ -40,108 +105,58 @@ class Net::Nic : public Net::Packet_handler
_nic.tx_channel()->sigh_ready_to_submit(_source_submit);
}
/******************************
** Packet_handler interface **
******************************/
Packet_stream_sink< ::Nic::Session::Policy> * sink() {
return _nic.rx(); }
Packet_stream_source< ::Nic::Session::Policy> * source() {
return _nic.tx(); }
static Nic *nic()
{
static Nic _net_nic;
return &_net_nic;
}
static ::Nic::Connection *n()
{
return &nic()->_nic;
}
Nic::Connection *nic() { return &_nic; }
};
Net::Packet_handler::Packet_handler()
: _sink_ack(*Net::Env::receiver(), *this, &Packet_handler::_ready_to_ack),
_sink_submit(*Net::Env::receiver(), *this, &Packet_handler::_packet_avail),
_source_ack(*Net::Env::receiver(), *this, &Packet_handler::_ack_avail),
_source_submit(*Net::Env::receiver(), *this, &Packet_handler::_ready_to_submit)
{ }
static Nic_client *_nic_client;
void Net::Packet_handler::_ack_avail(unsigned)
void Lx::nic_client_init(Genode::Signal_receiver &sig_rec)
{
while (source()->ack_avail())
source()->release_packet(source()->get_acked_packet());
}
void Net::Packet_handler::_ready_to_ack(unsigned num)
{
_packet_avail(num);
}
void Net::Packet_handler::_packet_avail(unsigned)
{
using namespace Net;
enum { MAX_PACKETS = 20 };
int count = 0;
while(Nic::n()->rx()->packet_avail() &&
Nic::n()->rx()->ready_to_ack() &&
count++ < MAX_PACKETS)
{
Packet_descriptor p = Nic::n()->rx()->get_packet();
net_driver_rx(Net::Nic::n()->rx()->packet_content(p), p.size());
Nic::n()->rx()->acknowledge_packet(p);
}
if (Nic::n()->rx()->packet_avail())
Genode::Signal_transmitter(_sink_submit).submit();
}
static void snprint_mac(unsigned char *buf, unsigned char *mac)
{
for (int i = 0; i < ETH_ALEN; i++) {
Genode::snprintf((char *)&buf[i * 3], 3, "%02x", mac[i]);
if ((i * 3) < MAC_LEN)
buf[(i * 3) + 2] = ':';
}
buf[MAC_LEN] = 0;
static Nic_client _inst(sig_rec);
_nic_client = &_inst;
}
/**
* Call by back-end driver while initializing
*/
void net_mac(void* mac, unsigned long size)
{
enum { MAC_LEN = 17, ETH_ALEN = 6, };
unsigned char str[MAC_LEN + 1];
using namespace Genode;
Nic::Mac_address m = Net::Nic::n()->mac_address();
Nic::Mac_address m = _nic_client->nic()->mac_address();
Genode::memcpy(mac, &m.addr, min(sizeof(m.addr), (size_t)size));
snprint_mac(str, (unsigned char *)m.addr);
unsigned char const *mac_addr = (unsigned char const*)m.addr;
for (int i = 0; i < ETH_ALEN; i++) {
Genode::snprintf((char *)&str[i * 3], 3, "%02x", mac_addr[i]);
if ((i * 3) < MAC_LEN)
str[(i * 3) + 2] = ':';
}
str[MAC_LEN] = 0;
PINF("Received mac: %s", str);
}
/**
* Call by back-end driver when a packet should be sent
*/
int net_tx(void* addr, unsigned long len)
{
try {
Net::Packet_descriptor packet = Net::Nic::n()->tx()->alloc_packet(len);
void* content = Net::Nic::n()->tx()->packet_content(packet);
Nic::Packet_descriptor packet = _nic_client->nic()->tx()->alloc_packet(len);
void* content = _nic_client->nic()->tx()->packet_content(packet);
Genode::memcpy((char *)content, addr, len);
Net::Nic::n()->tx()->submit_packet(packet);
_nic_client->nic()->tx()->submit_packet(packet);
return 0;
/* 'Packet_alloc_failed' */
} catch(...) {
return 1;
}
/* Packet_alloc_failed */
} catch(...) { return 1; }
}

View File

@ -1,115 +0,0 @@
/**
* \brief BSD style socket helpers
* \author Sebastian Sumpf
* \date 2013-08-28
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <linux/net.h>
#include <net/sock.h>
#include <net/tcp_states.h>
#include <lx_emul.h>
static const struct net_proto_family *net_families[NPROTO];
int sock_register(const struct net_proto_family *ops)
{
if (ops->family >= NPROTO) {
printk("protocol %d >= NPROTO (%d)\n", ops->family, NPROTO);
return -ENOBUFS;
}
net_families[ops->family] = ops;
pr_info("NET: Registered protocol family %d\n", ops->family);
return 0;
}
struct socket *sock_alloc(void)
{
return (struct socket *)kmalloc(sizeof(struct socket), 0);
}
int sock_create_lite(int family, int type, int protocol, struct socket **res)
{
struct socket *sock = sock_alloc();
if (!sock)
return -ENOMEM;
sock->type = type;
*res = sock;
return 0;
}
int sock_create_kern(int family, int type, int proto,
struct socket **res)
{
struct socket *sock;
const struct net_proto_family *pf;
int err;
if (family < 0 || family > NPROTO)
return -EAFNOSUPPORT;
if (type < 0 || type > SOCK_MAX)
return -EINVAL;
pf = net_families[family];
if (!pf) {
printk("No protocol found for family %d\n", family);
return -ENOPROTOOPT;
}
if (!(sock = (struct socket *)kzalloc(sizeof(struct socket), 0))) {
printk("Could not allocate socket\n");
return -ENFILE;
}
sock->type = type;
err = pf->create(&init_net, sock, proto, 1);
if (err) {
kfree(sock);
return err;
}
*res = sock;
return 0;
}
int socket_check_state(struct socket *socket)
{
if (socket->sk->sk_state == TCP_CLOSE_WAIT)
return -EINTR;
return 0;
}
void log_sock(struct socket *socket)
{
printk("\nNEW socket %p sk %p fsk %x &sk %p &fsk %p\n\n",
socket, socket->sk, socket->flags, &socket->sk, &socket->flags);
}
static void sock_init(void)
{
skb_init();
}
core_initcall(sock_init);

View File

@ -5,29 +5,31 @@
*/
/*
* Copyright (C) 2013 Genode Labs GmbH
* Copyright (C) 2013-2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/env.h>
#include <base/signal.h>
#include <base/printf.h>
#include <base/thread.h>
/* local includes */
#include <lxip/lxip.h>
#include <env.h>
#include <init.h>
#include <lx.h>
#include <nic.h>
extern "C" void wait_for_continue();
static const bool verbose = false;
namespace Linux {
#include <lx/extern_c_begin.h>
#include <lx_emul.h>
#include <lx_emul/extern_c_begin.h>
#include <linux/socket.h>
#include <uapi/linux/in.h>
extern int sock_setsockopt(struct socket *sock, int level,
@ -36,7 +38,8 @@ namespace Linux {
extern int sock_getsockopt(struct socket *sock, int level,
int op, char __user *optval,
int __user *optlen);
#include <lx/extern_c_end.h>
struct socket *sock_alloc(void);
#include <lx_emul/extern_c_end.h>
}
namespace Net
@ -105,7 +108,6 @@ namespace Net
int err;
Lxip::ssize_t len;
};
};
@ -120,8 +122,9 @@ class Net::Socketcall : public Genode::Signal_dispatcher_base,
Result _result;
Lxip::Handle _handle;
Genode::Signal_transmitter _signal;
Genode::Semaphore _block;
Genode::Signal_receiver &_sig_rec;
Genode::Signal_transmitter _signal;
Genode::Semaphore _block;
void _submit_and_block()
{
@ -169,8 +172,8 @@ class Net::Socketcall : public Genode::Signal_dispatcher_base,
{
using namespace Linux;
struct socket *sock = call_socket();
struct socket *new_sock = (struct socket *)kzalloc(sizeof(struct socket), 0);
struct socket *sock = call_socket();
struct socket *new_sock = sock_alloc();
_handle.socket = 0;
@ -187,7 +190,6 @@ class Net::Socketcall : public Genode::Signal_dispatcher_base,
_handle.socket = static_cast<void *>(new_sock);
if (!_call.accept.addr)
return;
@ -216,6 +218,7 @@ class Net::Socketcall : public Genode::Signal_dispatcher_base,
if (s->ops)
s->ops->release(s);
kfree(s->wq);
kfree(s);
}
@ -299,10 +302,12 @@ class Net::Socketcall : public Genode::Signal_dispatcher_base,
struct msghdr msg;
struct iovec iov;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iovlen = 1;
msg.msg_iov = &iov;
msg.msg_control = nullptr;
msg.msg_controllen = 0;
msg.msg_iter.iov = &iov;
msg.msg_iter.nr_segs = 1;
msg.msg_iter.count = _call.msg.len;
iov.iov_len = _call.msg.len;
iov.iov_base = _call.msg.buf;
msg.msg_name = _call.addr_len ? &_call.addr : 0;
@ -313,7 +318,7 @@ class Net::Socketcall : public Genode::Signal_dispatcher_base,
msg.msg_flags |= MSG_DONTWAIT;
//XXX: check for non-blocking flag
_result.len = call_socket()->ops->recvmsg(0, call_socket(), &msg,
_result.len = call_socket()->ops->recvmsg(call_socket(), &msg,
_call.msg.len,
_call.msg.flags);
@ -333,10 +338,12 @@ class Net::Socketcall : public Genode::Signal_dispatcher_base,
if (_result.len < 0)
return;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iovlen = 1;
msg.msg_iov = &iov;
msg.msg_control = nullptr;
msg.msg_controllen = 0;
msg.msg_iter.iov = &iov;
msg.msg_iter.nr_segs = 1;
msg.msg_iter.count = _call.msg.len;
iov.iov_len = _call.msg.len;
iov.iov_base = _call.msg.buf;
msg.msg_name = _call.addr_len ? &_call.addr : 0;
@ -346,7 +353,7 @@ class Net::Socketcall : public Genode::Signal_dispatcher_base,
if (_call.handle.non_block)
msg.msg_flags |= MSG_DONTWAIT;
_result.len = call_socket()->ops->sendmsg(0, call_socket(), &msg,
_result.len = call_socket()->ops->sendmsg(call_socket(), &msg,
_call.msg.len);
}
@ -370,32 +377,34 @@ class Net::Socketcall : public Genode::Signal_dispatcher_base,
int type = _call.socket.type == Lxip::TYPE_STREAM ? SOCK_STREAM :
SOCK_DGRAM;
struct socket *s = (struct socket *)kzalloc(sizeof(struct socket), 0);
struct socket *s = sock_alloc();
if (!sock_create_kern(AF_INET, type, 0, &s)) {
_handle.socket = static_cast<void *>(s);
if (sock_create_kern(nullptr, AF_INET, type, 0, &s)) {
_handle.socket = 0;
kfree(s);
return;
}
_handle.socket = 0;
kfree(s);
_handle.socket = static_cast<void *>(s);
}
public:
Socketcall()
: Thread_deprecated("socketcall"),
_signal(Genode::Signal_context_capability(Env::receiver()->manage(this)))
Socketcall(Genode::Signal_receiver &sig_rec)
:
Thread_deprecated("socketcall"),
_sig_rec(sig_rec),
_signal(Genode::Signal_context_capability(_sig_rec.manage(this)))
{
start();
}
~Socketcall() { Env::receiver()->dissolve(this); }
~Socketcall() { _sig_rec.dissolve(this); }
void entry()
{
while (true) {
Genode::Signal s = Net::Env::receiver()->wait_for_signal();
Genode::Signal s = _sig_rec.wait_for_signal();
static_cast<Genode::Signal_dispatcher_base *>(s.context())->dispatch(s.num());
}
}
@ -626,10 +635,16 @@ class Net::Socketcall : public Genode::Signal_dispatcher_base,
};
Lxip::Socketcall & Lxip::init(char *address_config)
Lxip::Socketcall & Lxip::init(char const *address_config)
{
static int init = lxip_init(address_config);
static Net::Socketcall socketcall;
static Genode::Signal_receiver sig_rec;
Lx::timer_init(sig_rec);
Lx::event_init(sig_rec);
Lx::nic_client_init(sig_rec);
static int init = lxip_init(address_config);
static Net::Socketcall socketcall(sig_rec);
return socketcall;
}

View File

@ -5,12 +5,13 @@
*/
/*
* Copyright (C) 2012-2013 Genode Labs GmbH
* Copyright (C) 2012-2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/env.h>
#include <base/printf.h>
#include <base/tslab.h>
@ -18,13 +19,12 @@
#include <timer_session/connection.h>
#include <util/volatile_object.h>
#include <lx/extern_c_begin.h>
/* Linux kit includes */
#include <lx_kit/internal/list.h>
/* local includes */
#include <lx_emul.h>
#include <lx/extern_c_end.h>
#include <env.h>
#include <lx/list.h>
#include <lx.h>
/*********************
@ -33,8 +33,6 @@
unsigned long jiffies;
unsigned long msecs_to_jiffies(const unsigned int m) { return m / (1000 / HZ); }
/**
* Lx::Timer
*/
@ -49,7 +47,7 @@ class Lx::Timer
/**
* Context encapsulates a regular linux timer_list
*/
struct Context : public Lx::List<Context>::Element
struct Context : public Lx_kit::List<Context>::Element
{
enum { INVALID_TIMEOUT = ~0UL };
enum Type { LIST };
@ -86,7 +84,7 @@ class Lx::Timer
private:
::Timer::Connection _timer_conn;
Lx::List<Context> _list;
Lx_kit::List<Context> _list;
Genode::Signal_dispatcher<Lx::Timer> _dispatcher;
Genode::Tslab<Context, 32 * sizeof(Context)> _timer_alloc;
@ -187,9 +185,9 @@ class Lx::Timer
/**
* Constructor
*/
Timer()
Timer(Genode::Signal_receiver &sig_rec)
:
_dispatcher(*Net::Env::receiver(), *this, &Lx::Timer::_handle),
_dispatcher(sig_rec, *this, &Lx::Timer::_handle),
_timer_alloc(Genode::env()->heap())
{
_timer_conn.sigh(_dispatcher);
@ -283,19 +281,22 @@ class Lx::Timer
* Get first timer context
*/
Context* first() { return _list.first(); }
static Timer &t()
{
static Lx::Timer _t;
return _t;
}
};
static Lx::Timer *_timer;
void Lx::timer_init(Genode::Signal_receiver &sig_rec)
{
static Lx::Timer inst(sig_rec);
_timer = &inst;
}
void update_jiffies()
{
Lx::Timer::t().update_jiffies();
_timer->update_jiffies();
}
@ -305,6 +306,7 @@ void update_jiffies()
void init_timer(struct timer_list *timer) { }
void add_timer(struct timer_list *timer)
{
BUG_ON(timer_pending(timer));
@ -312,15 +314,14 @@ void add_timer(struct timer_list *timer)
}
int mod_timer(struct timer_list *timer, unsigned long expires)
{
update_jiffies();
if (!Lx::Timer::t().find(timer))
Lx::Timer::t().add(timer);
if (!_timer->find(timer))
_timer->add(timer);
return Lx::Timer::t().schedule(timer, expires);
return _timer->schedule(timer, expires);
}
@ -334,7 +335,7 @@ void setup_timer(struct timer_list *timer,void (*function)(unsigned long),
int timer_pending(const struct timer_list * timer)
{
bool pending = Lx::Timer::t().pending(timer);
bool pending = _timer->pending(timer);
lx_log(DEBUG_TIMER, "Pending %p %u", timer, pending);
return pending;
}
@ -344,10 +345,8 @@ int del_timer(struct timer_list *timer)
{
update_jiffies();
lx_log(DEBUG_TIMER, "Delete timer %p", timer);
int rv = Lx::Timer::t().del(timer);
Lx::Timer::t().schedule_next();
int rv = _timer->del(timer);
_timer->schedule_next();
return rv;
}

View File

@ -0,0 +1,103 @@
/*
* \brief Minimal HTTP server demonstration using socket API
* \author Josef Soentgen
* \date 2016-03-22
*/
/*
* Copyright (C) 2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/printf.h>
/* libc includes */
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
const static char http_html_hdr[] =
"HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n"; /* HTTP response header */
const static char http_index_html[] =
"<html><head><title>Congrats!</title></head><body><h1>Welcome to our HTTP demonstration server!</h1><p>This is a small test page.</body></html>"; /* HTML page */
static void serve(int fd) {
char buf[1024];
ssize_t buflen;
/* Read the data from the port, blocking if nothing yet there.
We assume the request (the part we care about) is in one packet */
buflen = recv(fd, buf, 1024, 0);
// PLOG("Packet received!");
/* Ignore all receive errors */
if (buflen > 0) {
/* Is this an HTTP GET command? (only check the first 5 chars, since
there are other formats for GET, and we're keeping it very simple)*/
if (buflen >= 5 &&
buf[0] == 'G' &&
buf[1] == 'E' &&
buf[2] == 'T' &&
buf[3] == ' ' &&
buf[4] == '/' ) {
// PLOG("Will send response");
/* Send http header */
send(fd, http_html_hdr, sizeof(http_html_hdr), 0);
/* Send our HTML page */
send(fd, http_index_html, sizeof(http_index_html), 0);
}
}
}
int main()
{
int s;
PLOG("Create new socket ...");
if((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
PERR("No socket available!");
return -1;
}
PLOG("Now, I will bind ...");
struct sockaddr_in in_addr;
in_addr.sin_family = AF_INET;
in_addr.sin_port = htons(80);
in_addr.sin_addr.s_addr = INADDR_ANY;
if(bind(s, (struct sockaddr*)&in_addr, sizeof(in_addr))) {
PERR("bind failed!");
return -1;
}
PLOG("Now, I will listen ...");
if(listen(s, 5)) {
PERR("listen failed!");
return -1;
}
PLOG("Start the server loop ...");
while(true) {
struct sockaddr addr;
socklen_t len = sizeof(addr);
int client = accept(s, &addr, &len);
if(client < 0) {
PWRN("Invalid socket from accept!");
continue;
}
serve(client);
close(client);
}
return 0;
}

View File

@ -0,0 +1,3 @@
TARGET = test-lxip_http_srv
LIBS = libc libc_lxip
SRC_CC = main.cc

View File

@ -0,0 +1,72 @@
/*
* \brief Minimal datagram server demonstration using socket API
* \author Josef Soentgen
* \date 2016-04-22
*/
/*
* Copyright (C) 2016 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/printf.h>
/* libc includes */
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
int main(void)
{
int s;
PLOG("Create new socket ...");
if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
PERR("No socket available!");
return -1;
}
PLOG("Now, I will bind ...");
struct sockaddr_in in_addr;
in_addr.sin_family = AF_INET;
in_addr.sin_port = htons(1337);
in_addr.sin_addr.s_addr = INADDR_ANY;
if(bind(s, (struct sockaddr*)&in_addr, sizeof(in_addr))) {
PERR("bind failed!");
return -1;
}
PLOG("Start the server loop ...");
while(true) {
struct sockaddr_in addr;
addr.sin_family = AF_INET;
socklen_t len = sizeof(addr);
char buf[4096];
memset(buf, 0, sizeof(buf));
ssize_t n = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr*)&addr, &len);
if (n == 0) {
PWRN("Invalid request!");
continue;
}
if (n < 0) {
PERR("Error %lld", n);
break;
}
PLOG("Received %lld bytes", n);
n = sendto(s, buf, n, 0, (struct sockaddr*)&addr, len);
PLOG("Send %lld bytes back", n);
}
return 0;
}

View File

@ -0,0 +1,3 @@
TARGET = test-lxip_udp_echo
LIBS = libc libc_lxip
SRC_CC = main.cc