kernel: generic: Add kernel 4.14 support
This adds initial support for kernel 4.14 based on the patches for kernel 4.9. In the configuration I deactivated some of the new possible security features like: CONFIG_REFCOUNT_FULL CONFIG_SLAB_FREELIST_HARDENED CONFIG_SOFTLOCKUP_DETECTOR CONFIG_WARN_ALL_UNSEEDED_RANDOM And these overlay FS options are also deactivated: CONFIG_OVERLAY_FS_INDEX CONFIG_OVERLAY_FS_REDIRECT_DIR I activated this: CONFIG_FORTIFY_SOURCE CONFIG_POSIX_TIMERS CONFIG_SLAB_MERGE_DEFAULT CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED I am not sure if I did the porting correct for the following patches: target/linux/generic/backport-4.14/020-backport_netfilter_rtcache.patch target/linux/generic/hack-4.14/220-gc_sections.patch target/linux/generic/hack-4.14/321-powerpc_crtsavres_prereq.patch target/linux/generic/pending-4.14/305-mips_module_reloc.patch target/linux/generic/pending-4.14/611-netfilter_match_bypass_default_table.patch target/linux/generic/pending-4.14/680-NET-skip-GRO-for-foreign-MAC-addresses.patch Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
		| @@ -5,10 +5,12 @@ LINUX_RELEASE?=1 | |||||||
| LINUX_VERSION-3.18 = .71 | LINUX_VERSION-3.18 = .71 | ||||||
| LINUX_VERSION-4.4 = .100 | LINUX_VERSION-4.4 = .100 | ||||||
| LINUX_VERSION-4.9 = .67 | LINUX_VERSION-4.9 = .67 | ||||||
|  | LINUX_VERSION-4.14 = .6 | ||||||
|  |  | ||||||
| LINUX_KERNEL_HASH-3.18.71 = 5abc9778ad44ce02ed6c8ab52ece8a21c6d20d21f6ed8a19287b4a38a50c1240 | LINUX_KERNEL_HASH-3.18.71 = 5abc9778ad44ce02ed6c8ab52ece8a21c6d20d21f6ed8a19287b4a38a50c1240 | ||||||
| LINUX_KERNEL_HASH-4.4.100 = 9936cd99c4bd35f6bc6962c9acdd1fa2ac8999e07a9be6a94a03b5492f1bd14f | LINUX_KERNEL_HASH-4.4.100 = 9936cd99c4bd35f6bc6962c9acdd1fa2ac8999e07a9be6a94a03b5492f1bd14f | ||||||
| LINUX_KERNEL_HASH-4.9.67 = 7fbaa7dcc17877dfa0c96fb9a7d2f4ffed20ceeb13cbbeb18d77213c6cf75f7d | LINUX_KERNEL_HASH-4.9.67 = 7fbaa7dcc17877dfa0c96fb9a7d2f4ffed20ceeb13cbbeb18d77213c6cf75f7d | ||||||
|  | LINUX_KERNEL_HASH-4.14.6 = 0907678ba9ea146ddbdecd0a0b6363f56b896b5c61c9a15e809effb3ea346ccc | ||||||
|  |  | ||||||
| ifdef KERNEL_PATCHVER | ifdef KERNEL_PATCHVER | ||||||
|   LINUX_VERSION:=$(KERNEL_PATCHVER)$(strip $(LINUX_VERSION-$(KERNEL_PATCHVER))) |   LINUX_VERSION:=$(KERNEL_PATCHVER)$(strip $(LINUX_VERSION-$(KERNEL_PATCHVER))) | ||||||
|   | |||||||
| @@ -0,0 +1,30 @@ | |||||||
|  | From 13b1ecc3401653a355798eb1dee10cc1608202f4 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Mon, 18 Jan 2016 12:27:49 +0100 | ||||||
|  | Subject: [PATCH 33/34] Kbuild: don't hardcode path to awk in | ||||||
|  |  scripts/ld-version.sh | ||||||
|  |  | ||||||
|  | On some systems /usr/bin/awk does not exist, or is broken. Find it via | ||||||
|  | $PATH instead. | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  scripts/ld-version.sh | 4 +++- | ||||||
|  |  1 file changed, 3 insertions(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/scripts/ld-version.sh | ||||||
|  | +++ b/scripts/ld-version.sh | ||||||
|  | @@ -1,6 +1,7 @@ | ||||||
|  | -#!/usr/bin/awk -f | ||||||
|  | +#!/bin/sh | ||||||
|  |  # SPDX-License-Identifier: GPL-2.0 | ||||||
|  |  # extract linker version number from stdin and turn into single number | ||||||
|  | +exec awk ' | ||||||
|  |  	{ | ||||||
|  |  	gsub(".*\\)", ""); | ||||||
|  |  	gsub(".*version ", ""); | ||||||
|  | @@ -9,3 +10,4 @@ | ||||||
|  |  	print a[1]*100000000 + a[2]*1000000 + a[3]*10000; | ||||||
|  |  	exit | ||||||
|  |  	} | ||||||
|  | +' | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | From 173019b66dcc9d68ad9333aa744dad1e369b5aa8 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Sun, 9 Jul 2017 00:26:53 +0200 | ||||||
|  | Subject: [PATCH 34/34] kernel: add compile fix for linux 4.9 on x86 | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  Makefile | 4 ++-- | ||||||
|  |  1 file changed, 2 insertions(+), 2 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/Makefile | ||||||
|  | +++ b/Makefile | ||||||
|  | @@ -415,8 +415,8 @@ KERNELRELEASE = $(shell cat include/conf | ||||||
|  |  KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION) | ||||||
|  |   | ||||||
|  |  export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION | ||||||
|  | -export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC | ||||||
|  | -export CPP AR NM STRIP OBJCOPY OBJDUMP HOSTLDFLAGS HOST_LOADLIBES | ||||||
|  | +export ARCH SRCARCH SUBARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD | ||||||
|  | +export CC CPP AR NM STRIP OBJCOPY OBJDUMP HOSTLDFLAGS HOST_LOADLIBES | ||||||
|  |  export MAKE AWK GENKSYMS INSTALLKERNEL PERL PYTHON UTS_MACHINE | ||||||
|  |  export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS | ||||||
|  |   | ||||||
| @@ -0,0 +1,558 @@ | |||||||
|  | From 1bb0c3ec899827cfa4668bb63a08713a40744d21 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Florian Westphal <fw@strlen.de> | ||||||
|  | Date: Sun, 9 Jul 2017 08:58:30 +0200 | ||||||
|  | Subject: [PATCH] netfilter: conntrack: cache route for forwarded connections | ||||||
|  |  | ||||||
|  | ... to avoid per-packet FIB lookup if possible. | ||||||
|  |  | ||||||
|  | The cached dst is re-used provided the input interface | ||||||
|  | is the same as that of the previous packet in the same direction. | ||||||
|  |  | ||||||
|  | If not, the cached dst is invalidated. | ||||||
|  |  | ||||||
|  | For ipv6 we also need to store sernum, else dst_check doesn't work, | ||||||
|  | pointed out by Eric Dumazet. | ||||||
|  |  | ||||||
|  | This should speed up forwarding when conntrack is already in use | ||||||
|  | anyway, especially when using reverse path filtering -- active RPF | ||||||
|  | enforces two FIB lookups for each packet. | ||||||
|  |  | ||||||
|  | Before the routing cache removal this didn't matter since RPF was performed | ||||||
|  | only when route cache didn't yield a result; but without route cache it | ||||||
|  | comes at higher price. | ||||||
|  |  | ||||||
|  | Julian Anastasov suggested to add NETDEV_UNREGISTER handler to | ||||||
|  | avoid holding on to dsts of 'frozen' conntracks. | ||||||
|  |  | ||||||
|  | Signed-off-by: Florian Westphal <fw@strlen.de> | ||||||
|  | --- | ||||||
|  |  include/net/netfilter/nf_conntrack_extend.h  |   4 + | ||||||
|  |  include/net/netfilter/nf_conntrack_rtcache.h |  34 +++ | ||||||
|  |  net/netfilter/Kconfig                        |  12 + | ||||||
|  |  net/netfilter/Makefile                       |   3 + | ||||||
|  |  net/netfilter/nf_conntrack_rtcache.c         | 428 +++++++++++++++++++++++++++ | ||||||
|  |  5 files changed, 481 insertions(+) | ||||||
|  |  create mode 100644 include/net/netfilter/nf_conntrack_rtcache.h | ||||||
|  |  create mode 100644 net/netfilter/nf_conntrack_rtcache.c | ||||||
|  |  | ||||||
|  | --- a/include/net/netfilter/nf_conntrack_extend.h | ||||||
|  | +++ b/include/net/netfilter/nf_conntrack_extend.h | ||||||
|  | @@ -28,6 +28,9 @@ enum nf_ct_ext_id { | ||||||
|  |  #if IS_ENABLED(CONFIG_NETFILTER_SYNPROXY) | ||||||
|  |  	NF_CT_EXT_SYNPROXY, | ||||||
|  |  #endif | ||||||
|  | +#if IS_ENABLED(CONFIG_NF_CONNTRACK_RTCACHE) | ||||||
|  | +	NF_CT_EXT_RTCACHE, | ||||||
|  | +#endif | ||||||
|  |  	NF_CT_EXT_NUM, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | @@ -40,6 +43,7 @@ enum nf_ct_ext_id { | ||||||
|  |  #define NF_CT_EXT_TIMEOUT_TYPE struct nf_conn_timeout | ||||||
|  |  #define NF_CT_EXT_LABELS_TYPE struct nf_conn_labels | ||||||
|  |  #define NF_CT_EXT_SYNPROXY_TYPE struct nf_conn_synproxy | ||||||
|  | +#define NF_CT_EXT_RTCACHE_TYPE struct nf_conn_rtcache | ||||||
|  |   | ||||||
|  |  /* Extensions: optional stuff which isn't permanently in struct. */ | ||||||
|  |  struct nf_ct_ext { | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/include/net/netfilter/nf_conntrack_rtcache.h | ||||||
|  | @@ -0,0 +1,34 @@ | ||||||
|  | +#include <linux/gfp.h> | ||||||
|  | +#include <net/netfilter/nf_conntrack.h> | ||||||
|  | +#include <net/netfilter/nf_conntrack_extend.h> | ||||||
|  | + | ||||||
|  | +struct dst_entry; | ||||||
|  | + | ||||||
|  | +struct nf_conn_dst_cache { | ||||||
|  | +	struct dst_entry *dst; | ||||||
|  | +	int iif; | ||||||
|  | +#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) | ||||||
|  | +	u32 cookie; | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +struct nf_conn_rtcache { | ||||||
|  | +	struct nf_conn_dst_cache cached_dst[IP_CT_DIR_MAX]; | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +static inline | ||||||
|  | +struct nf_conn_rtcache *nf_ct_rtcache_find(const struct nf_conn *ct) | ||||||
|  | +{ | ||||||
|  | +#if IS_ENABLED(CONFIG_NF_CONNTRACK_RTCACHE) | ||||||
|  | +	return nf_ct_ext_find(ct, NF_CT_EXT_RTCACHE); | ||||||
|  | +#else | ||||||
|  | +	return NULL; | ||||||
|  | +#endif | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static inline int nf_conn_rtcache_iif_get(const struct nf_conn_rtcache *rtc, | ||||||
|  | +					  enum ip_conntrack_dir dir) | ||||||
|  | +{ | ||||||
|  | +	return rtc->cached_dst[dir].iif; | ||||||
|  | +} | ||||||
|  | --- a/net/netfilter/Kconfig | ||||||
|  | +++ b/net/netfilter/Kconfig | ||||||
|  | @@ -118,6 +118,18 @@ config NF_CONNTRACK_EVENTS | ||||||
|  |   | ||||||
|  |  	  If unsure, say `N'. | ||||||
|  |   | ||||||
|  | +config NF_CONNTRACK_RTCACHE | ||||||
|  | +	tristate "Cache route entries in conntrack objects" | ||||||
|  | +	depends on NETFILTER_ADVANCED | ||||||
|  | +	depends on NF_CONNTRACK | ||||||
|  | +	help | ||||||
|  | +	  If this option is enabled, the connection tracking code will | ||||||
|  | +	  cache routing information for each connection that is being | ||||||
|  | +	  forwarded, at a cost of 32 bytes per conntrack object. | ||||||
|  | + | ||||||
|  | +	  To compile it as a module, choose M here.  If unsure, say N. | ||||||
|  | +	  The module will be called nf_conntrack_rtcache. | ||||||
|  | + | ||||||
|  |  config NF_CONNTRACK_TIMEOUT | ||||||
|  |  	bool  'Connection tracking timeout' | ||||||
|  |  	depends on NETFILTER_ADVANCED | ||||||
|  | --- a/net/netfilter/Makefile | ||||||
|  | +++ b/net/netfilter/Makefile | ||||||
|  | @@ -19,6 +19,9 @@ obj-$(CONFIG_NETFILTER_NETLINK_LOG) += n | ||||||
|  |  # connection tracking | ||||||
|  |  obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o | ||||||
|  |   | ||||||
|  | +# optional conntrack route cache extension | ||||||
|  | +obj-$(CONFIG_NF_CONNTRACK_RTCACHE) += nf_conntrack_rtcache.o | ||||||
|  | + | ||||||
|  |  obj-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o | ||||||
|  |   | ||||||
|  |  # netlink interface for nf_conntrack | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/net/netfilter/nf_conntrack_rtcache.c | ||||||
|  | @@ -0,0 +1,428 @@ | ||||||
|  | +/* route cache for netfilter. | ||||||
|  | + * | ||||||
|  | + * (C) 2014 Red Hat GmbH | ||||||
|  | + * | ||||||
|  | + * This program is free software; you can redistribute it and/or modify | ||||||
|  | + * it under the terms of the GNU General Public License version 2 as | ||||||
|  | + * published by the Free Software Foundation. | ||||||
|  | + */ | ||||||
|  | + | ||||||
|  | +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||||||
|  | + | ||||||
|  | +#include <linux/types.h> | ||||||
|  | +#include <linux/netfilter.h> | ||||||
|  | +#include <linux/skbuff.h> | ||||||
|  | +#include <linux/stddef.h> | ||||||
|  | +#include <linux/kernel.h> | ||||||
|  | +#include <linux/netdevice.h> | ||||||
|  | +#include <linux/export.h> | ||||||
|  | +#include <linux/module.h> | ||||||
|  | + | ||||||
|  | +#include <net/dst.h> | ||||||
|  | + | ||||||
|  | +#include <net/netfilter/nf_conntrack.h> | ||||||
|  | +#include <net/netfilter/nf_conntrack_core.h> | ||||||
|  | +#include <net/netfilter/nf_conntrack_extend.h> | ||||||
|  | +#include <net/netfilter/nf_conntrack_rtcache.h> | ||||||
|  | + | ||||||
|  | +#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) | ||||||
|  | +#include <net/ip6_fib.h> | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  | +static void __nf_conn_rtcache_destroy(struct nf_conn_rtcache *rtc, | ||||||
|  | +				      enum ip_conntrack_dir dir) | ||||||
|  | +{ | ||||||
|  | +	struct dst_entry *dst = rtc->cached_dst[dir].dst; | ||||||
|  | + | ||||||
|  | +	dst_release(dst); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void nf_conn_rtcache_destroy(struct nf_conn *ct) | ||||||
|  | +{ | ||||||
|  | +	struct nf_conn_rtcache *rtc = nf_ct_rtcache_find(ct); | ||||||
|  | + | ||||||
|  | +	if (!rtc) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	__nf_conn_rtcache_destroy(rtc, IP_CT_DIR_ORIGINAL); | ||||||
|  | +	__nf_conn_rtcache_destroy(rtc, IP_CT_DIR_REPLY); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void nf_ct_rtcache_ext_add(struct nf_conn *ct) | ||||||
|  | +{ | ||||||
|  | +	struct nf_conn_rtcache *rtc; | ||||||
|  | + | ||||||
|  | +	rtc = nf_ct_ext_add(ct, NF_CT_EXT_RTCACHE, GFP_ATOMIC); | ||||||
|  | +	if (rtc) { | ||||||
|  | +		rtc->cached_dst[IP_CT_DIR_ORIGINAL].iif = -1; | ||||||
|  | +		rtc->cached_dst[IP_CT_DIR_ORIGINAL].dst = NULL; | ||||||
|  | +		rtc->cached_dst[IP_CT_DIR_REPLY].iif = -1; | ||||||
|  | +		rtc->cached_dst[IP_CT_DIR_REPLY].dst = NULL; | ||||||
|  | +	} | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static struct nf_conn_rtcache *nf_ct_rtcache_find_usable(struct nf_conn *ct) | ||||||
|  | +{ | ||||||
|  | +	return nf_ct_rtcache_find(ct); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static struct dst_entry * | ||||||
|  | +nf_conn_rtcache_dst_get(const struct nf_conn_rtcache *rtc, | ||||||
|  | +			enum ip_conntrack_dir dir) | ||||||
|  | +{ | ||||||
|  | +	return rtc->cached_dst[dir].dst; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static u32 nf_rtcache_get_cookie(int pf, const struct dst_entry *dst) | ||||||
|  | +{ | ||||||
|  | +#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) | ||||||
|  | +	if (pf == NFPROTO_IPV6) { | ||||||
|  | +		const struct rt6_info *rt = (const struct rt6_info *)dst; | ||||||
|  | + | ||||||
|  | +		if (rt->rt6i_node) | ||||||
|  | +			return (u32)rt->rt6i_node->fn_sernum; | ||||||
|  | +	} | ||||||
|  | +#endif | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void nf_conn_rtcache_dst_set(int pf, | ||||||
|  | +				    struct nf_conn_rtcache *rtc, | ||||||
|  | +				    struct dst_entry *dst, | ||||||
|  | +				    enum ip_conntrack_dir dir, int iif) | ||||||
|  | +{ | ||||||
|  | +	if (rtc->cached_dst[dir].iif != iif) | ||||||
|  | +		rtc->cached_dst[dir].iif = iif; | ||||||
|  | + | ||||||
|  | +	if (rtc->cached_dst[dir].dst != dst) { | ||||||
|  | +		struct dst_entry *old; | ||||||
|  | + | ||||||
|  | +		dst_hold(dst); | ||||||
|  | + | ||||||
|  | +		old = xchg(&rtc->cached_dst[dir].dst, dst); | ||||||
|  | +		dst_release(old); | ||||||
|  | + | ||||||
|  | +#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) | ||||||
|  | +		if (pf == NFPROTO_IPV6) | ||||||
|  | +			rtc->cached_dst[dir].cookie = | ||||||
|  | +				nf_rtcache_get_cookie(pf, dst); | ||||||
|  | +#endif | ||||||
|  | +	} | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void nf_conn_rtcache_dst_obsolete(struct nf_conn_rtcache *rtc, | ||||||
|  | +					 enum ip_conntrack_dir dir) | ||||||
|  | +{ | ||||||
|  | +	struct dst_entry *old; | ||||||
|  | + | ||||||
|  | +	pr_debug("Invalidate iif %d for dir %d on cache %p\n", | ||||||
|  | +		 rtc->cached_dst[dir].iif, dir, rtc); | ||||||
|  | + | ||||||
|  | +	old = xchg(&rtc->cached_dst[dir].dst, NULL); | ||||||
|  | +	dst_release(old); | ||||||
|  | +	rtc->cached_dst[dir].iif = -1; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static unsigned int nf_rtcache_in(u_int8_t pf, | ||||||
|  | +				  struct sk_buff *skb, | ||||||
|  | +				  const struct nf_hook_state *state) | ||||||
|  | +{ | ||||||
|  | +	struct nf_conn_rtcache *rtc; | ||||||
|  | +	enum ip_conntrack_info ctinfo; | ||||||
|  | +	enum ip_conntrack_dir dir; | ||||||
|  | +	struct dst_entry *dst; | ||||||
|  | +	struct nf_conn *ct; | ||||||
|  | +	int iif; | ||||||
|  | +	u32 cookie; | ||||||
|  | + | ||||||
|  | +	if (skb_dst(skb) || skb->sk) | ||||||
|  | +		return NF_ACCEPT; | ||||||
|  | + | ||||||
|  | +	ct = nf_ct_get(skb, &ctinfo); | ||||||
|  | +	if (!ct) | ||||||
|  | +		return NF_ACCEPT; | ||||||
|  | + | ||||||
|  | +	rtc = nf_ct_rtcache_find_usable(ct); | ||||||
|  | +	if (!rtc) | ||||||
|  | +		return NF_ACCEPT; | ||||||
|  | + | ||||||
|  | +	/* if iif changes, don't use cache and let ip stack | ||||||
|  | +	 * do route lookup. | ||||||
|  | +	 * | ||||||
|  | +	 * If rp_filter is enabled it might toss skb, so | ||||||
|  | +	 * we don't want to avoid these checks. | ||||||
|  | +	 */ | ||||||
|  | +	dir = CTINFO2DIR(ctinfo); | ||||||
|  | +	iif = nf_conn_rtcache_iif_get(rtc, dir); | ||||||
|  | +	if (state->in->ifindex != iif) { | ||||||
|  | +		pr_debug("ct %p, iif %d, cached iif %d, skip cached entry\n", | ||||||
|  | +			 ct, iif, state->in->ifindex); | ||||||
|  | +		return NF_ACCEPT; | ||||||
|  | +	} | ||||||
|  | +	dst = nf_conn_rtcache_dst_get(rtc, dir); | ||||||
|  | +	if (dst == NULL) | ||||||
|  | +		return NF_ACCEPT; | ||||||
|  | + | ||||||
|  | +	cookie = nf_rtcache_get_cookie(pf, dst); | ||||||
|  | + | ||||||
|  | +	dst = dst_check(dst, cookie); | ||||||
|  | +	pr_debug("obtained dst %p for skb %p, cookie %d\n", dst, skb, cookie); | ||||||
|  | +	if (likely(dst)) | ||||||
|  | +		skb_dst_set_noref(skb, dst); | ||||||
|  | +	else | ||||||
|  | +		nf_conn_rtcache_dst_obsolete(rtc, dir); | ||||||
|  | + | ||||||
|  | +	return NF_ACCEPT; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static unsigned int nf_rtcache_forward(u_int8_t pf, | ||||||
|  | +				       struct sk_buff *skb, | ||||||
|  | +				       const struct nf_hook_state *state) | ||||||
|  | +{ | ||||||
|  | +	struct nf_conn_rtcache *rtc; | ||||||
|  | +	enum ip_conntrack_info ctinfo; | ||||||
|  | +	enum ip_conntrack_dir dir; | ||||||
|  | +	struct nf_conn *ct; | ||||||
|  | +	struct dst_entry *dst = skb_dst(skb); | ||||||
|  | +	int iif; | ||||||
|  | + | ||||||
|  | +	ct = nf_ct_get(skb, &ctinfo); | ||||||
|  | +	if (!ct) | ||||||
|  | +		return NF_ACCEPT; | ||||||
|  | + | ||||||
|  | +	if (dst && dst_xfrm(dst)) | ||||||
|  | +		return NF_ACCEPT; | ||||||
|  | + | ||||||
|  | +	if (!nf_ct_is_confirmed(ct)) { | ||||||
|  | +		if (WARN_ON(nf_ct_rtcache_find(ct))) | ||||||
|  | +			return NF_ACCEPT; | ||||||
|  | +		nf_ct_rtcache_ext_add(ct); | ||||||
|  | +		return NF_ACCEPT; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	rtc = nf_ct_rtcache_find_usable(ct); | ||||||
|  | +	if (!rtc) | ||||||
|  | +		return NF_ACCEPT; | ||||||
|  | + | ||||||
|  | +	dir = CTINFO2DIR(ctinfo); | ||||||
|  | +	iif = nf_conn_rtcache_iif_get(rtc, dir); | ||||||
|  | +	pr_debug("ct %p, skb %p, dir %d, iif %d, cached iif %d\n", | ||||||
|  | +		 ct, skb, dir, iif, state->in->ifindex); | ||||||
|  | +	if (likely(state->in->ifindex == iif)) | ||||||
|  | +		return NF_ACCEPT; | ||||||
|  | + | ||||||
|  | +	nf_conn_rtcache_dst_set(pf, rtc, skb_dst(skb), dir, state->in->ifindex); | ||||||
|  | +	return NF_ACCEPT; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static unsigned int nf_rtcache_in4(void *priv, | ||||||
|  | +				  struct sk_buff *skb, | ||||||
|  | +				  const struct nf_hook_state *state) | ||||||
|  | +{ | ||||||
|  | +	return nf_rtcache_in(NFPROTO_IPV4, skb, state); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static unsigned int nf_rtcache_forward4(void *priv, | ||||||
|  | +				       struct sk_buff *skb, | ||||||
|  | +				       const struct nf_hook_state *state) | ||||||
|  | +{ | ||||||
|  | +	return nf_rtcache_forward(NFPROTO_IPV4, skb, state); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) | ||||||
|  | +static unsigned int nf_rtcache_in6(void *priv, | ||||||
|  | +				  struct sk_buff *skb, | ||||||
|  | +				  const struct nf_hook_state *state) | ||||||
|  | +{ | ||||||
|  | +	return nf_rtcache_in(NFPROTO_IPV6, skb, state); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static unsigned int nf_rtcache_forward6(void *priv, | ||||||
|  | +				       struct sk_buff *skb, | ||||||
|  | +				       const struct nf_hook_state *state) | ||||||
|  | +{ | ||||||
|  | + 	return nf_rtcache_forward(NFPROTO_IPV6, skb, state); | ||||||
|  | +} | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  | +static int nf_rtcache_dst_remove(struct nf_conn *ct, void *data) | ||||||
|  | +{ | ||||||
|  | +	struct nf_conn_rtcache *rtc = nf_ct_rtcache_find(ct); | ||||||
|  | +	struct net_device *dev = data; | ||||||
|  | + | ||||||
|  | +	if (!rtc) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  | +	if (dev->ifindex == rtc->cached_dst[IP_CT_DIR_ORIGINAL].iif || | ||||||
|  | +	    dev->ifindex == rtc->cached_dst[IP_CT_DIR_REPLY].iif) { | ||||||
|  | +		nf_conn_rtcache_dst_obsolete(rtc, IP_CT_DIR_ORIGINAL); | ||||||
|  | +		nf_conn_rtcache_dst_obsolete(rtc, IP_CT_DIR_REPLY); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int nf_rtcache_netdev_event(struct notifier_block *this, | ||||||
|  | +				   unsigned long event, void *ptr) | ||||||
|  | +{ | ||||||
|  | +	struct net_device *dev = netdev_notifier_info_to_dev(ptr); | ||||||
|  | +	struct net *net = dev_net(dev); | ||||||
|  | + | ||||||
|  | +	if (event == NETDEV_DOWN) | ||||||
|  | +		nf_ct_iterate_cleanup_net(net, nf_rtcache_dst_remove, dev, 0, 0); | ||||||
|  | + | ||||||
|  | +	return NOTIFY_DONE; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static struct notifier_block nf_rtcache_notifier = { | ||||||
|  | +	.notifier_call = nf_rtcache_netdev_event, | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +static struct nf_hook_ops rtcache_ops[] = { | ||||||
|  | +	{ | ||||||
|  | +		.hook		= nf_rtcache_in4, | ||||||
|  | +		.pf		= NFPROTO_IPV4, | ||||||
|  | +		.hooknum	= NF_INET_PRE_ROUTING, | ||||||
|  | +		.priority       = NF_IP_PRI_LAST, | ||||||
|  | +	}, | ||||||
|  | +	{ | ||||||
|  | +		.hook           = nf_rtcache_forward4, | ||||||
|  | +		.pf             = NFPROTO_IPV4, | ||||||
|  | +		.hooknum        = NF_INET_FORWARD, | ||||||
|  | +		.priority       = NF_IP_PRI_LAST, | ||||||
|  | +	}, | ||||||
|  | +#if IS_ENABLED(CONFIG_NF_CONNTRACK_IPV6) | ||||||
|  | +	{ | ||||||
|  | +		.hook		= nf_rtcache_in6, | ||||||
|  | +		.pf		= NFPROTO_IPV6, | ||||||
|  | +		.hooknum	= NF_INET_PRE_ROUTING, | ||||||
|  | +		.priority       = NF_IP_PRI_LAST, | ||||||
|  | +	}, | ||||||
|  | +	{ | ||||||
|  | +		.hook           = nf_rtcache_forward6, | ||||||
|  | +		.pf             = NFPROTO_IPV6, | ||||||
|  | +		.hooknum        = NF_INET_FORWARD, | ||||||
|  | +		.priority       = NF_IP_PRI_LAST, | ||||||
|  | +	}, | ||||||
|  | +#endif | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +static struct nf_ct_ext_type rtcache_extend __read_mostly = { | ||||||
|  | +	.len	= sizeof(struct nf_conn_rtcache), | ||||||
|  | +	.align	= __alignof__(struct nf_conn_rtcache), | ||||||
|  | +	.id	= NF_CT_EXT_RTCACHE, | ||||||
|  | +	.destroy = nf_conn_rtcache_destroy, | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +static void __net_exit rtcache_net_exit(struct net *net) | ||||||
|  | +{ | ||||||
|  | +	/* remove hooks so no new connections get rtcache extension */ | ||||||
|  | +	nf_unregister_net_hooks(net, rtcache_ops, ARRAY_SIZE(rtcache_ops)); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static struct pernet_operations rtcache_ops_net_ops = { | ||||||
|  | +	.exit	= rtcache_net_exit, | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +static int __init nf_conntrack_rtcache_init(void) | ||||||
|  | +{ | ||||||
|  | +	int ret = nf_ct_extend_register(&rtcache_extend); | ||||||
|  | + | ||||||
|  | +	if (ret < 0) { | ||||||
|  | +		pr_err("nf_conntrack_rtcache: Unable to register extension\n"); | ||||||
|  | +		return ret; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	ret = register_pernet_subsys(&rtcache_ops_net_ops); | ||||||
|  | +	if (ret) { | ||||||
|  | +		nf_ct_extend_unregister(&rtcache_extend); | ||||||
|  | +		return ret; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	ret = nf_register_net_hooks(&init_net, rtcache_ops, | ||||||
|  | +				    ARRAY_SIZE(rtcache_ops)); | ||||||
|  | +	if (ret < 0) { | ||||||
|  | +		nf_ct_extend_unregister(&rtcache_extend); | ||||||
|  | +		unregister_pernet_subsys(&rtcache_ops_net_ops); | ||||||
|  | +		return ret; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	ret = register_netdevice_notifier(&nf_rtcache_notifier); | ||||||
|  | +	if (ret) { | ||||||
|  | +		nf_unregister_net_hooks(&init_net, rtcache_ops, | ||||||
|  | +					ARRAY_SIZE(rtcache_ops)); | ||||||
|  | +		nf_ct_extend_unregister(&rtcache_extend); | ||||||
|  | +		unregister_pernet_subsys(&rtcache_ops_net_ops); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return ret; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int nf_rtcache_ext_remove(struct nf_conn *ct, void *data) | ||||||
|  | +{ | ||||||
|  | +	struct nf_conn_rtcache *rtc = nf_ct_rtcache_find(ct); | ||||||
|  | + | ||||||
|  | +	return rtc != NULL; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static bool __exit nf_conntrack_rtcache_wait_for_dying(struct net *net) | ||||||
|  | +{ | ||||||
|  | +	bool wait = false; | ||||||
|  | +	int cpu; | ||||||
|  | + | ||||||
|  | +	for_each_possible_cpu(cpu) { | ||||||
|  | +		struct nf_conntrack_tuple_hash *h; | ||||||
|  | +		struct hlist_nulls_node *n; | ||||||
|  | +		struct nf_conn *ct; | ||||||
|  | +		struct ct_pcpu *pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu); | ||||||
|  | + | ||||||
|  | +		rcu_read_lock(); | ||||||
|  | +		spin_lock_bh(&pcpu->lock); | ||||||
|  | + | ||||||
|  | +		hlist_nulls_for_each_entry(h, n, &pcpu->dying, hnnode) { | ||||||
|  | +			ct = nf_ct_tuplehash_to_ctrack(h); | ||||||
|  | +			if (nf_ct_rtcache_find(ct) != NULL) { | ||||||
|  | +				wait = true; | ||||||
|  | +				break; | ||||||
|  | +			} | ||||||
|  | +		} | ||||||
|  | +		spin_unlock_bh(&pcpu->lock); | ||||||
|  | +		rcu_read_unlock(); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return wait; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void __exit nf_conntrack_rtcache_fini(void) | ||||||
|  | +{ | ||||||
|  | +	struct net *net; | ||||||
|  | +	int count = 0; | ||||||
|  | + | ||||||
|  | +	synchronize_net(); | ||||||
|  | + | ||||||
|  | +	unregister_netdevice_notifier(&nf_rtcache_notifier); | ||||||
|  | + | ||||||
|  | +	rtnl_lock(); | ||||||
|  | + | ||||||
|  | +	/* zap all conntracks with rtcache extension */ | ||||||
|  | +	for_each_net(net) | ||||||
|  | +		nf_ct_iterate_cleanup_net(net, nf_rtcache_ext_remove, NULL, 0, 0); | ||||||
|  | + | ||||||
|  | +	for_each_net(net) { | ||||||
|  | +		/* .. and make sure they're gone from dying list, too */ | ||||||
|  | +		while (nf_conntrack_rtcache_wait_for_dying(net)) { | ||||||
|  | +			msleep(200); | ||||||
|  | +			WARN_ONCE(++count > 25, "Waiting for all rtcache conntracks to go away\n"); | ||||||
|  | +		} | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	rtnl_unlock(); | ||||||
|  | +	synchronize_net(); | ||||||
|  | +	nf_ct_extend_unregister(&rtcache_extend); | ||||||
|  | +} | ||||||
|  | +module_init(nf_conntrack_rtcache_init); | ||||||
|  | +module_exit(nf_conntrack_rtcache_fini); | ||||||
|  | + | ||||||
|  | +MODULE_LICENSE("GPL"); | ||||||
|  | +MODULE_AUTHOR("Florian Westphal <fw@strlen.de>"); | ||||||
|  | +MODULE_DESCRIPTION("Conntrack route cache extension"); | ||||||
| @@ -0,0 +1,85 @@ | |||||||
|  | From: Eric Dumazet <edumazet@google.com> | ||||||
|  | Date: Sat, 11 Nov 2017 15:54:12 -0800 | ||||||
|  | Subject: [PATCH] tcp: allow drivers to tweak TSQ logic | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Type: text/plain; charset=UTF-8 | ||||||
|  | Content-Transfer-Encoding: 8bit | ||||||
|  |  | ||||||
|  | I had many reports that TSQ logic breaks wifi aggregation. | ||||||
|  |  | ||||||
|  | Current logic is to allow up to 1 ms of bytes to be queued into qdisc | ||||||
|  | and drivers queues. | ||||||
|  |  | ||||||
|  | But Wifi aggregation needs a bigger budget to allow bigger rates to | ||||||
|  | be discovered by various TCP Congestion Controls algorithms. | ||||||
|  |  | ||||||
|  | This patch adds an extra socket field, allowing wifi drivers to select | ||||||
|  | another log scale to derive TCP Small Queue credit from current pacing | ||||||
|  | rate. | ||||||
|  |  | ||||||
|  | Initial value is 10, meaning that this patch does not change current | ||||||
|  | behavior. | ||||||
|  |  | ||||||
|  | We expect wifi drivers to set this field to smaller values (tests have | ||||||
|  | been done with values from 6 to 9) | ||||||
|  |  | ||||||
|  | They would have to use following template : | ||||||
|  |  | ||||||
|  | if (skb->sk && skb->sk->sk_pacing_shift != MY_PACING_SHIFT) | ||||||
|  |      skb->sk->sk_pacing_shift = MY_PACING_SHIFT; | ||||||
|  |  | ||||||
|  | Ref: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1670041 | ||||||
|  | Signed-off-by: Eric Dumazet <edumazet@google.com> | ||||||
|  | Cc: Johannes Berg <johannes.berg@intel.com> | ||||||
|  | Cc: Toke Høiland-Jørgensen <toke@toke.dk> | ||||||
|  | Cc: Kir Kolyshkin <kir@openvz.org> | ||||||
|  | --- | ||||||
|  | --- a/include/net/sock.h | ||||||
|  | +++ b/include/net/sock.h | ||||||
|  | @@ -267,6 +267,7 @@ struct sock_common { | ||||||
|  |    *	@sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4) | ||||||
|  |    *	@sk_gso_max_size: Maximum GSO segment size to build | ||||||
|  |    *	@sk_gso_max_segs: Maximum number of GSO segments | ||||||
|  | +  *	@sk_pacing_shift: scaling factor for TCP Small Queues | ||||||
|  |    *	@sk_lingertime: %SO_LINGER l_linger setting | ||||||
|  |    *	@sk_backlog: always used with the per-socket spinlock held | ||||||
|  |    *	@sk_callback_lock: used with the callbacks in the end of this struct | ||||||
|  | @@ -448,6 +449,8 @@ struct sock { | ||||||
|  |  	kmemcheck_bitfield_end(flags); | ||||||
|  |   | ||||||
|  |  	u16			sk_gso_max_segs; | ||||||
|  | +#define sk_pacing_shift sk_pacing_shift /* for backport checks */ | ||||||
|  | +	u8			sk_pacing_shift; | ||||||
|  |  	unsigned long	        sk_lingertime; | ||||||
|  |  	struct proto		*sk_prot_creator; | ||||||
|  |  	rwlock_t		sk_callback_lock; | ||||||
|  | --- a/net/core/sock.c | ||||||
|  | +++ b/net/core/sock.c | ||||||
|  | @@ -2744,6 +2744,7 @@ void sock_init_data(struct socket *sock, | ||||||
|  |   | ||||||
|  |  	sk->sk_max_pacing_rate = ~0U; | ||||||
|  |  	sk->sk_pacing_rate = ~0U; | ||||||
|  | +	sk->sk_pacing_shift = 10; | ||||||
|  |  	sk->sk_incoming_cpu = -1; | ||||||
|  |  	/* | ||||||
|  |  	 * Before updating sk_refcnt, we must commit prior changes to memory | ||||||
|  | --- a/net/ipv4/tcp_output.c | ||||||
|  | +++ b/net/ipv4/tcp_output.c | ||||||
|  | @@ -1671,7 +1671,7 @@ u32 tcp_tso_autosize(const struct sock * | ||||||
|  |  { | ||||||
|  |  	u32 bytes, segs; | ||||||
|  |   | ||||||
|  | -	bytes = min(sk->sk_pacing_rate >> 10, | ||||||
|  | +	bytes = min(sk->sk_pacing_rate >> sk->sk_pacing_shift, | ||||||
|  |  		    sk->sk_gso_max_size - 1 - MAX_TCP_HEADER); | ||||||
|  |   | ||||||
|  |  	/* Goal is to send at least one packet per ms, | ||||||
|  | @@ -2145,7 +2145,7 @@ static bool tcp_small_queue_check(struct | ||||||
|  |  { | ||||||
|  |  	unsigned int limit; | ||||||
|  |   | ||||||
|  | -	limit = max(2 * skb->truesize, sk->sk_pacing_rate >> 10); | ||||||
|  | +	limit = max(2 * skb->truesize, sk->sk_pacing_rate >> sk->sk_pacing_shift); | ||||||
|  |  	limit = min_t(u32, limit, sysctl_tcp_limit_output_bytes); | ||||||
|  |  	limit <<= factor; | ||||||
|  |   | ||||||
| @@ -0,0 +1,50 @@ | |||||||
|  | From 12acd136913ccdf394eeb2bc8686ff5505368119 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||||
|  | Date: Thu, 12 Oct 2017 10:21:26 +0200 | ||||||
|  | Subject: [PATCH] net: bgmac: enable master mode for BCM54210E and B50212E PHYs | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Type: text/plain; charset=UTF-8 | ||||||
|  | Content-Transfer-Encoding: 8bit | ||||||
|  |  | ||||||
|  | There are 4 very similar PHYs: | ||||||
|  | 0x600d84a1: BCM54210E (rev B0) | ||||||
|  | 0x600d84a2: BCM54210E (rev B1) | ||||||
|  | 0x600d84a5: B50212E (rev B0) | ||||||
|  | 0x600d84a6: B50212E (rev B1) | ||||||
|  | that need setting master mode manually. It's because they run in slave | ||||||
|  | mode by default with Automatic Slave/Master configuration disabled which | ||||||
|  | can lead to unreliable connection with massive ping loss. | ||||||
|  |  | ||||||
|  | So far it was reported for a board with BCM47189 SoC and B50212E B1 PHY | ||||||
|  | connected to the bgmac supported ethernet device. Telling PHY driver to | ||||||
|  | setup PHY properly solves this issue. | ||||||
|  |  | ||||||
|  | Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||||
|  | Signed-off-by: David S. Miller <davem@davemloft.net> | ||||||
|  | --- | ||||||
|  |  drivers/net/ethernet/broadcom/bgmac-bcma.c | 8 +++++++- | ||||||
|  |  1 file changed, 7 insertions(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/ethernet/broadcom/bgmac-bcma.c | ||||||
|  | +++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c | ||||||
|  | @@ -184,13 +184,19 @@ static int bgmac_probe(struct bcma_devic | ||||||
|  |   | ||||||
|  |  	if (!bgmac_is_bcm4707_family(core) && | ||||||
|  |  	    !(ci->id == BCMA_CHIP_ID_BCM53573 && core->core_unit == 1)) { | ||||||
|  | +		struct phy_device *phydev; | ||||||
|  | + | ||||||
|  |  		mii_bus = bcma_mdio_mii_register(bgmac); | ||||||
|  |  		if (IS_ERR(mii_bus)) { | ||||||
|  |  			err = PTR_ERR(mii_bus); | ||||||
|  |  			goto err; | ||||||
|  |  		} | ||||||
|  | - | ||||||
|  |  		bgmac->mii_bus = mii_bus; | ||||||
|  | + | ||||||
|  | +		phydev = mdiobus_get_phy(bgmac->mii_bus, bgmac->phyaddr); | ||||||
|  | +		if (ci->id == BCMA_CHIP_ID_BCM53573 && phydev && | ||||||
|  | +		    (phydev->drv->phy_id & phydev->drv->phy_id_mask) == PHY_ID_BCM54210E) | ||||||
|  | +			phydev->dev_flags |= PHY_BRCM_EN_MASTER_MODE; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) { | ||||||
| @@ -0,0 +1,54 @@ | |||||||
|  | From 2355a6546a053b1c16ebefd6ce1f0cccc00e1da5 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||||
|  | Date: Thu, 12 Oct 2017 10:21:25 +0200 | ||||||
|  | Subject: [PATCH] net: phy: broadcom: support new device flag for setting | ||||||
|  |  master mode | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Type: text/plain; charset=UTF-8 | ||||||
|  | Content-Transfer-Encoding: 8bit | ||||||
|  |  | ||||||
|  | Some of Broadcom's PHYs run by default in slave mode with Automatic | ||||||
|  | Slave/Master configuration disabled. It stops them from working properly | ||||||
|  | with some devices. | ||||||
|  |  | ||||||
|  | So far it has been verified for BCM54210E and BCM50212E which don't | ||||||
|  | work well with Intel's I217-LM and I218-LM: | ||||||
|  | http://ark.intel.com/products/60019/Intel-Ethernet-Connection-I217-LM | ||||||
|  | http://ark.intel.com/products/71307/Intel-Ethernet-Connection-I218-LM | ||||||
|  | I was told there is massive ping loss. | ||||||
|  |  | ||||||
|  | This commit adds support for a new flag which can be set by an ethernet | ||||||
|  | driver to fixup PHY setup. | ||||||
|  |  | ||||||
|  | Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||||
|  | Signed-off-by: David S. Miller <davem@davemloft.net> | ||||||
|  | --- | ||||||
|  |  drivers/net/phy/broadcom.c | 6 ++++++ | ||||||
|  |  include/linux/brcmphy.h    | 1 + | ||||||
|  |  2 files changed, 7 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/phy/broadcom.c | ||||||
|  | +++ b/drivers/net/phy/broadcom.c | ||||||
|  | @@ -43,6 +43,12 @@ static int bcm54210e_config_init(struct | ||||||
|  |  	val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN; | ||||||
|  |  	bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val); | ||||||
|  |   | ||||||
|  | +	if (phydev->dev_flags & PHY_BRCM_EN_MASTER_MODE) { | ||||||
|  | +		val = phy_read(phydev, MII_CTRL1000); | ||||||
|  | +		val |= CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER; | ||||||
|  | +		phy_write(phydev, MII_CTRL1000, val); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | --- a/include/linux/brcmphy.h | ||||||
|  | +++ b/include/linux/brcmphy.h | ||||||
|  | @@ -64,6 +64,7 @@ | ||||||
|  |  #define PHY_BRCM_EXT_IBND_TX_ENABLE	0x00002000 | ||||||
|  |  #define PHY_BRCM_CLEAR_RGMII_MODE	0x00004000 | ||||||
|  |  #define PHY_BRCM_DIS_TXCRXC_NOENRGY	0x00008000 | ||||||
|  | +#define PHY_BRCM_EN_MASTER_MODE		0x00010000 | ||||||
|  |   | ||||||
|  |  /* Broadcom BCM7xxx specific workarounds */ | ||||||
|  |  #define PHY_BRCM_7XXX_REV(x)		(((x) >> 8) & 0xff) | ||||||
							
								
								
									
										5591
									
								
								target/linux/generic/config-4.14
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5591
									
								
								target/linux/generic/config-4.14
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -24,6 +24,7 @@ | |||||||
| #include <linux/kernel.h> | #include <linux/kernel.h> | ||||||
| #include <linux/module.h> | #include <linux/module.h> | ||||||
| #include <linux/switch.h> | #include <linux/switch.h> | ||||||
|  | #include <linux/phy.h> | ||||||
| #include <linux/of.h> | #include <linux/of.h> | ||||||
| #include <linux/of_net.h> | #include <linux/of_net.h> | ||||||
| #include <linux/platform_data/b53.h> | #include <linux/platform_data/b53.h> | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ | |||||||
| #include <linux/switch.h> | #include <linux/switch.h> | ||||||
| #include <linux/delay.h> | #include <linux/delay.h> | ||||||
| #include <linux/phy.h> | #include <linux/phy.h> | ||||||
|  | #include <linux/version.h> | ||||||
|  |  | ||||||
| //#define DEBUG 1 | //#define DEBUG 1 | ||||||
|  |  | ||||||
| @@ -1032,7 +1033,9 @@ rtl8306_read_status(struct phy_device *pdev) | |||||||
|  |  | ||||||
| static struct phy_driver rtl8306_driver = { | static struct phy_driver rtl8306_driver = { | ||||||
| 	.name		= "Realtek RTL8306S", | 	.name		= "Realtek RTL8306S", | ||||||
|  | #if (LINUX_VERSION_CODE < KERNEL_VERSION(4,13,0)) | ||||||
| 	.flags		= PHY_HAS_MAGICANEG, | 	.flags		= PHY_HAS_MAGICANEG, | ||||||
|  | #endif | ||||||
| 	.phy_id		= RTL8306_MAGIC, | 	.phy_id		= RTL8306_MAGIC, | ||||||
| 	.phy_id_mask	= 0xffffffff, | 	.phy_id_mask	= 0xffffffff, | ||||||
| 	.features	= PHY_BASIC_FEATURES, | 	.features	= PHY_BASIC_FEATURES, | ||||||
|   | |||||||
| @@ -269,13 +269,7 @@ static void swconfig_defaults_init(struct switch_dev *dev) | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| static struct genl_family switch_fam = { | static struct genl_family switch_fam; | ||||||
| 	.id = GENL_ID_GENERATE, |  | ||||||
| 	.name = "switch", |  | ||||||
| 	.hdrsize = 0, |  | ||||||
| 	.version = 1, |  | ||||||
| 	.maxattr = SWITCH_ATTR_MAX, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static const struct nla_policy switch_policy[SWITCH_ATTR_MAX+1] = { | static const struct nla_policy switch_policy[SWITCH_ATTR_MAX+1] = { | ||||||
| 	[SWITCH_ATTR_ID] = { .type = NLA_U32 }, | 	[SWITCH_ATTR_ID] = { .type = NLA_U32 }, | ||||||
| @@ -597,8 +591,13 @@ swconfig_parse_ports(struct sk_buff *msg, struct nlattr *head, | |||||||
|  |  | ||||||
| 		port = &val->value.ports[val->len]; | 		port = &val->value.ports[val->len]; | ||||||
|  |  | ||||||
|  | #if LINUX_VERSION_CODE < KERNEL_VERSION(4,12,0) | ||||||
| 		if (nla_parse_nested(tb, SWITCH_PORT_ATTR_MAX, nla, | 		if (nla_parse_nested(tb, SWITCH_PORT_ATTR_MAX, nla, | ||||||
| 				port_policy)) | 				port_policy)) | ||||||
|  | #else | ||||||
|  | 		if (nla_parse_nested(tb, SWITCH_PORT_ATTR_MAX, nla, | ||||||
|  | 				port_policy, NULL)) | ||||||
|  | #endif | ||||||
| 			return -EINVAL; | 			return -EINVAL; | ||||||
|  |  | ||||||
| 		if (!tb[SWITCH_PORT_ID]) | 		if (!tb[SWITCH_PORT_ID]) | ||||||
| @@ -619,7 +618,11 @@ swconfig_parse_link(struct sk_buff *msg, struct nlattr *nla, | |||||||
| { | { | ||||||
| 	struct nlattr *tb[SWITCH_LINK_ATTR_MAX + 1]; | 	struct nlattr *tb[SWITCH_LINK_ATTR_MAX + 1]; | ||||||
|  |  | ||||||
|  | #if LINUX_VERSION_CODE < KERNEL_VERSION(4,12,0) | ||||||
| 	if (nla_parse_nested(tb, SWITCH_LINK_ATTR_MAX, nla, link_policy)) | 	if (nla_parse_nested(tb, SWITCH_LINK_ATTR_MAX, nla, link_policy)) | ||||||
|  | #else | ||||||
|  | 	if (nla_parse_nested(tb, SWITCH_LINK_ATTR_MAX, nla, link_policy, NULL)) | ||||||
|  | #endif | ||||||
| 		return -EINVAL; | 		return -EINVAL; | ||||||
|  |  | ||||||
| 	link->duplex = !!tb[SWITCH_LINK_FLAG_DUPLEX]; | 	link->duplex = !!tb[SWITCH_LINK_FLAG_DUPLEX]; | ||||||
| @@ -1051,6 +1054,19 @@ static struct genl_ops swconfig_ops[] = { | |||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | static struct genl_family switch_fam = { | ||||||
|  | #if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0) | ||||||
|  | 	.id = GENL_ID_GENERATE, | ||||||
|  | #endif | ||||||
|  | 	.name = "switch", | ||||||
|  | 	.hdrsize = 0, | ||||||
|  | 	.version = 1, | ||||||
|  | 	.maxattr = SWITCH_ATTR_MAX, | ||||||
|  | 	.module = THIS_MODULE, | ||||||
|  | 	.ops = swconfig_ops, | ||||||
|  | 	.n_ops = ARRAY_SIZE(swconfig_ops), | ||||||
|  | }; | ||||||
|  |  | ||||||
| #ifdef CONFIG_OF | #ifdef CONFIG_OF | ||||||
| void | void | ||||||
| of_switch_load_portmap(struct switch_dev *dev) | of_switch_load_portmap(struct switch_dev *dev) | ||||||
| @@ -1223,7 +1239,11 @@ swconfig_init(void) | |||||||
| { | { | ||||||
| 	INIT_LIST_HEAD(&swdevs); | 	INIT_LIST_HEAD(&swdevs); | ||||||
|  |  | ||||||
|  | #if LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0) | ||||||
| 	return genl_register_family_with_ops(&switch_fam, swconfig_ops); | 	return genl_register_family_with_ops(&switch_fam, swconfig_ops); | ||||||
|  | #else | ||||||
|  | 	return genl_register_family(&switch_fam); | ||||||
|  | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| static void __exit | static void __exit | ||||||
|   | |||||||
							
								
								
									
										24
									
								
								target/linux/generic/hack-4.14/202-reduce_module_size.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								target/linux/generic/hack-4.14/202-reduce_module_size.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | From fd66884da2f96d2a7ea73f58b1b86251b959a913 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Fri, 7 Jul 2017 16:56:19 +0200 | ||||||
|  | Subject: kernel: strip unnecessary symbol table information from kernel modules | ||||||
|  |  | ||||||
|  | reduces default squashfs size on ar71xx by about 4k | ||||||
|  |  | ||||||
|  | lede-commit: 058d331a39077f159ca8922f1f422a1346d6aa67 | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  Makefile | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/Makefile | ||||||
|  | +++ b/Makefile | ||||||
|  | @@ -408,7 +408,7 @@ KBUILD_CFLAGS_KERNEL := | ||||||
|  |  KBUILD_AFLAGS   := -D__ASSEMBLY__ $(call cc-option,-fno-PIE) | ||||||
|  |  KBUILD_AFLAGS_MODULE  := -DMODULE | ||||||
|  |  KBUILD_CFLAGS_MODULE  := -DMODULE | ||||||
|  | -KBUILD_LDFLAGS_MODULE := -T $(srctree)/scripts/module-common.lds | ||||||
|  | +KBUILD_LDFLAGS_MODULE = -T $(srctree)/scripts/module-common.lds $(if $(CONFIG_PROFILING),,-s) | ||||||
|  |   | ||||||
|  |  # Read KERNELRELEASE from include/config/kernel.release (if it exists) | ||||||
|  |  KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null) | ||||||
							
								
								
									
										205
									
								
								target/linux/generic/hack-4.14/204-module_strip.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										205
									
								
								target/linux/generic/hack-4.14/204-module_strip.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,205 @@ | |||||||
|  | From a779a482fb9b9f8fcdf8b2519c789b4b9bb5dd05 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Fri, 7 Jul 2017 16:56:48 +0200 | ||||||
|  | Subject: build: add a hack for removing non-essential module info | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  include/linux/module.h      | 13 ++++++++----- | ||||||
|  |  include/linux/moduleparam.h | 15 ++++++++++++--- | ||||||
|  |  init/Kconfig                |  7 +++++++ | ||||||
|  |  kernel/module.c             |  5 ++++- | ||||||
|  |  scripts/mod/modpost.c       | 12 ++++++++++++ | ||||||
|  |  5 files changed, 43 insertions(+), 9 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/include/linux/module.h | ||||||
|  | +++ b/include/linux/module.h | ||||||
|  | @@ -158,6 +158,7 @@ extern void cleanup_module(void); | ||||||
|  |   | ||||||
|  |  /* Generic info of form tag = "info" */ | ||||||
|  |  #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info) | ||||||
|  | +#define MODULE_INFO_STRIP(tag, info) __MODULE_INFO_STRIP(tag, tag, info) | ||||||
|  |   | ||||||
|  |  /* For userspace: you can also call me... */ | ||||||
|  |  #define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias) | ||||||
|  | @@ -201,12 +202,12 @@ extern void cleanup_module(void); | ||||||
|  |   * Author(s), use "Name <email>" or just "Name", for multiple | ||||||
|  |   * authors use multiple MODULE_AUTHOR() statements/lines. | ||||||
|  |   */ | ||||||
|  | -#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author) | ||||||
|  | +#define MODULE_AUTHOR(_author) MODULE_INFO_STRIP(author, _author) | ||||||
|  |   | ||||||
|  |  /* What your module does. */ | ||||||
|  | -#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description) | ||||||
|  | +#define MODULE_DESCRIPTION(_description) MODULE_INFO_STRIP(description, _description) | ||||||
|  |   | ||||||
|  | -#ifdef MODULE | ||||||
|  | +#if defined(MODULE) && !defined(CONFIG_MODULE_STRIPPED) | ||||||
|  |  /* Creates an alias so file2alias.c can find device table. */ | ||||||
|  |  #define MODULE_DEVICE_TABLE(type, name)					\ | ||||||
|  |  extern typeof(name) __mod_##type##__##name##_device_table		\ | ||||||
|  | @@ -233,7 +234,9 @@ extern typeof(name) __mod_##type##__##na | ||||||
|  |   */ | ||||||
|  |   | ||||||
|  |  #if defined(MODULE) || !defined(CONFIG_SYSFS) | ||||||
|  | -#define MODULE_VERSION(_version) MODULE_INFO(version, _version) | ||||||
|  | +#define MODULE_VERSION(_version) MODULE_INFO_STRIP(version, _version) | ||||||
|  | +#elif defined(CONFIG_MODULE_STRIPPED) | ||||||
|  | +#define MODULE_VERSION(_version) __MODULE_INFO_DISABLED(version) | ||||||
|  |  #else | ||||||
|  |  #define MODULE_VERSION(_version)					\ | ||||||
|  |  	static struct module_version_attribute ___modver_attr = {	\ | ||||||
|  | @@ -255,7 +258,7 @@ extern typeof(name) __mod_##type##__##na | ||||||
|  |  /* Optional firmware file (or files) needed by the module | ||||||
|  |   * format is simply firmware file name.  Multiple firmware | ||||||
|  |   * files require multiple MODULE_FIRMWARE() specifiers */ | ||||||
|  | -#define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware) | ||||||
|  | +#define MODULE_FIRMWARE(_firmware) MODULE_INFO_STRIP(firmware, _firmware) | ||||||
|  |   | ||||||
|  |  struct notifier_block; | ||||||
|  |   | ||||||
|  | --- a/include/linux/moduleparam.h | ||||||
|  | +++ b/include/linux/moduleparam.h | ||||||
|  | @@ -17,6 +17,16 @@ | ||||||
|  |  /* Chosen so that structs with an unsigned long line up. */ | ||||||
|  |  #define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long)) | ||||||
|  |   | ||||||
|  | +/* This struct is here for syntactic coherency, it is not used */ | ||||||
|  | +#define __MODULE_INFO_DISABLED(name)					  \ | ||||||
|  | +  struct __UNIQUE_ID(name) {} | ||||||
|  | + | ||||||
|  | +#ifdef CONFIG_MODULE_STRIPPED | ||||||
|  | +#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO_DISABLED(name) | ||||||
|  | +#else | ||||||
|  | +#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO(tag, name, info) | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  |  #ifdef MODULE | ||||||
|  |  #define __MODULE_INFO(tag, name, info)					  \ | ||||||
|  |  static const char __UNIQUE_ID(name)[]					  \ | ||||||
|  | @@ -24,8 +34,7 @@ static const char __UNIQUE_ID(name)[] | ||||||
|  |    = __stringify(tag) "=" info | ||||||
|  |  #else  /* !MODULE */ | ||||||
|  |  /* This struct is here for syntactic coherency, it is not used */ | ||||||
|  | -#define __MODULE_INFO(tag, name, info)					  \ | ||||||
|  | -  struct __UNIQUE_ID(name) {} | ||||||
|  | +#define __MODULE_INFO(tag, name, info) __MODULE_INFO_DISABLED(name) | ||||||
|  |  #endif | ||||||
|  |  #define __MODULE_PARM_TYPE(name, _type)					  \ | ||||||
|  |    __MODULE_INFO(parmtype, name##type, #name ":" _type) | ||||||
|  | @@ -33,7 +42,7 @@ static const char __UNIQUE_ID(name)[] | ||||||
|  |  /* One for each parameter, describing how to use it.  Some files do | ||||||
|  |     multiple of these per line, so can't just use MODULE_INFO. */ | ||||||
|  |  #define MODULE_PARM_DESC(_parm, desc) \ | ||||||
|  | -	__MODULE_INFO(parm, _parm, #_parm ":" desc) | ||||||
|  | +	__MODULE_INFO_STRIP(parm, _parm, #_parm ":" desc) | ||||||
|  |   | ||||||
|  |  struct kernel_param; | ||||||
|  |   | ||||||
|  | --- a/init/Kconfig | ||||||
|  | +++ b/init/Kconfig | ||||||
|  | @@ -1896,6 +1896,13 @@ config TRIM_UNUSED_KSYMS | ||||||
|  |   | ||||||
|  |  	  If unsure, or if you need to build out-of-tree modules, say N. | ||||||
|  |   | ||||||
|  | +config MODULE_STRIPPED | ||||||
|  | +	bool "Reduce module size" | ||||||
|  | +	depends on MODULES | ||||||
|  | +	help | ||||||
|  | +	  Remove module parameter descriptions, author info, version, aliases, | ||||||
|  | +	  device tables, etc. | ||||||
|  | + | ||||||
|  |  endif # MODULES | ||||||
|  |   | ||||||
|  |  config MODULES_TREE_LOOKUP | ||||||
|  | --- a/kernel/module.c | ||||||
|  | +++ b/kernel/module.c | ||||||
|  | @@ -2997,9 +2997,11 @@ static struct module *setup_load_info(st | ||||||
|  |   | ||||||
|  |  static int check_modinfo(struct module *mod, struct load_info *info, int flags) | ||||||
|  |  { | ||||||
|  | -	const char *modmagic = get_modinfo(info, "vermagic"); | ||||||
|  |  	int err; | ||||||
|  |   | ||||||
|  | +#ifndef CONFIG_MODULE_STRIPPED | ||||||
|  | +	const char *modmagic = get_modinfo(info, "vermagic"); | ||||||
|  | + | ||||||
|  |  	if (flags & MODULE_INIT_IGNORE_VERMAGIC) | ||||||
|  |  		modmagic = NULL; | ||||||
|  |   | ||||||
|  | @@ -3020,6 +3022,7 @@ static int check_modinfo(struct module * | ||||||
|  |  				mod->name); | ||||||
|  |  		add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK); | ||||||
|  |  	} | ||||||
|  | +#endif | ||||||
|  |   | ||||||
|  |  	if (get_modinfo(info, "staging")) { | ||||||
|  |  		add_taint_module(mod, TAINT_CRAP, LOCKDEP_STILL_OK); | ||||||
|  | --- a/scripts/mod/modpost.c | ||||||
|  | +++ b/scripts/mod/modpost.c | ||||||
|  | @@ -1982,7 +1982,9 @@ static void read_symbols(char *modname) | ||||||
|  |  		symname = remove_dot(info.strtab + sym->st_name); | ||||||
|  |   | ||||||
|  |  		handle_modversions(mod, &info, sym, symname); | ||||||
|  | +#ifndef CONFIG_MODULE_STRIPPED | ||||||
|  |  		handle_moddevtable(mod, &info, sym, symname); | ||||||
|  | +#endif | ||||||
|  |  	} | ||||||
|  |  	if (!is_vmlinux(modname) || | ||||||
|  |  	     (is_vmlinux(modname) && vmlinux_section_warnings)) | ||||||
|  | @@ -2143,8 +2145,10 @@ static void add_header(struct buffer *b, | ||||||
|  |  	buf_printf(b, "#include <linux/vermagic.h>\n"); | ||||||
|  |  	buf_printf(b, "#include <linux/compiler.h>\n"); | ||||||
|  |  	buf_printf(b, "\n"); | ||||||
|  | +#ifndef CONFIG_MODULE_STRIPPED | ||||||
|  |  	buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n"); | ||||||
|  |  	buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n"); | ||||||
|  | +#endif | ||||||
|  |  	buf_printf(b, "\n"); | ||||||
|  |  	buf_printf(b, "__visible struct module __this_module\n"); | ||||||
|  |  	buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n"); | ||||||
|  | @@ -2161,16 +2165,20 @@ static void add_header(struct buffer *b, | ||||||
|  |   | ||||||
|  |  static void add_intree_flag(struct buffer *b, int is_intree) | ||||||
|  |  { | ||||||
|  | +#ifndef CONFIG_MODULE_STRIPPED | ||||||
|  |  	if (is_intree) | ||||||
|  |  		buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n"); | ||||||
|  | +#endif | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void add_staging_flag(struct buffer *b, const char *name) | ||||||
|  |  { | ||||||
|  | +#ifndef CONFIG_MODULE_STRIPPED | ||||||
|  |  	static const char *staging_dir = "drivers/staging"; | ||||||
|  |   | ||||||
|  |  	if (strncmp(staging_dir, name, strlen(staging_dir)) == 0) | ||||||
|  |  		buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); | ||||||
|  | +#endif | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /** | ||||||
|  | @@ -2269,11 +2277,13 @@ static void add_depends(struct buffer *b | ||||||
|  |   | ||||||
|  |  static void add_srcversion(struct buffer *b, struct module *mod) | ||||||
|  |  { | ||||||
|  | +#ifndef CONFIG_MODULE_STRIPPED | ||||||
|  |  	if (mod->srcversion[0]) { | ||||||
|  |  		buf_printf(b, "\n"); | ||||||
|  |  		buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n", | ||||||
|  |  			   mod->srcversion); | ||||||
|  |  	} | ||||||
|  | +#endif | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void write_if_changed(struct buffer *b, const char *fname) | ||||||
|  | @@ -2509,7 +2519,9 @@ int main(int argc, char **argv) | ||||||
|  |  		add_staging_flag(&buf, mod->name); | ||||||
|  |  		err |= add_versions(&buf, mod); | ||||||
|  |  		add_depends(&buf, mod, modules); | ||||||
|  | +#ifndef CONFIG_MODULE_STRIPPED | ||||||
|  |  		add_moddevtable(&buf, mod); | ||||||
|  | +#endif | ||||||
|  |  		add_srcversion(&buf, mod); | ||||||
|  |   | ||||||
|  |  		sprintf(fname, "%s.mod.c", mod->name); | ||||||
							
								
								
									
										44
									
								
								target/linux/generic/hack-4.14/207-disable-modorder.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								target/linux/generic/hack-4.14/207-disable-modorder.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | From c9ef4ab0f54356ee9f91d9676ea0ec123840ddc7 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Fri, 7 Jul 2017 16:57:33 +0200 | ||||||
|  | Subject: kernel: do not build modules.order | ||||||
|  |  | ||||||
|  | It is not needed for anything on the system and skipping this saves some | ||||||
|  | build time, especially in cases where there is nothing to do. | ||||||
|  |  | ||||||
|  | lede-commit: afc1675833a7bf5df094f59f7250369520646d04 | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  Makefile               | 2 -- | ||||||
|  |  scripts/Makefile.build | 2 +- | ||||||
|  |  2 files changed, 1 insertion(+), 3 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/Makefile | ||||||
|  | +++ b/Makefile | ||||||
|  | @@ -1208,7 +1208,6 @@ all: modules | ||||||
|  |   | ||||||
|  |  PHONY += modules | ||||||
|  |  modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin | ||||||
|  | -	$(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order | ||||||
|  |  	@$(kecho) '  Building modules, stage 2.'; | ||||||
|  |  	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost | ||||||
|  |   | ||||||
|  | @@ -1237,7 +1236,6 @@ _modinst_: | ||||||
|  |  		rm -f $(MODLIB)/build ; \ | ||||||
|  |  		ln -s $(CURDIR) $(MODLIB)/build ; \ | ||||||
|  |  	fi | ||||||
|  | -	@cp -f $(objtree)/modules.order $(MODLIB)/ | ||||||
|  |  	@cp -f $(objtree)/modules.builtin $(MODLIB)/ | ||||||
|  |  	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst | ||||||
|  |   | ||||||
|  | --- a/scripts/Makefile.build | ||||||
|  | +++ b/scripts/Makefile.build | ||||||
|  | @@ -94,7 +94,7 @@ modorder-target := $(obj)/modules.order | ||||||
|  |  # We keep a list of all modules in $(MODVERDIR) | ||||||
|  |   | ||||||
|  |  __build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \ | ||||||
|  | -	 $(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \ | ||||||
|  | +	 $(if $(KBUILD_MODULES),$(obj-m)) \ | ||||||
|  |  	 $(subdir-ym) $(always) | ||||||
|  |  	@: | ||||||
|  |   | ||||||
							
								
								
									
										3065
									
								
								target/linux/generic/hack-4.14/210-darwin_scripts_include.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3065
									
								
								target/linux/generic/hack-4.14/210-darwin_scripts_include.patch
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | From 7f698012384ccb1ed10cc758acfd085096fdb307 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Fri, 7 Jul 2017 17:02:03 +0200 | ||||||
|  | Subject: kernel: fix linux 4.9 host tools portability issues | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  tools/build/Build.include       | 2 +- | ||||||
|  |  tools/perf/pmu-events/jevents.c | 1 + | ||||||
|  |  tools/perf/pmu-events/json.c    | 1 - | ||||||
|  |  3 files changed, 2 insertions(+), 2 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/tools/build/Build.include | ||||||
|  | +++ b/tools/build/Build.include | ||||||
|  | @@ -97,4 +97,4 @@ cxx_flags = -Wp,-MD,$(depfile) -Wp,-MT,$ | ||||||
|  |  ### | ||||||
|  |  ## HOSTCC C flags | ||||||
|  |   | ||||||
|  | -host_c_flags = -Wp,-MD,$(depfile) -Wp,-MT,$@ $(CHOSTFLAGS) -D"BUILD_STR(s)=\#s" $(CHOSTFLAGS_$(basetarget).o) $(CHOSTFLAGS_$(obj)) | ||||||
|  | +host_c_flags = -MD -MF $(depfile) -Wp -MT $@ $(CHOSTFLAGS) -D"BUILD_STR(s)=\#s" $(CHOSTFLAGS_$(basetarget).o) $(CHOSTFLAGS_$(obj)) | ||||||
|  | --- a/tools/perf/pmu-events/jevents.c | ||||||
|  | +++ b/tools/perf/pmu-events/jevents.c | ||||||
|  | @@ -35,6 +35,7 @@ | ||||||
|  |  #include <stdlib.h> | ||||||
|  |  #include <errno.h> | ||||||
|  |  #include <string.h> | ||||||
|  | +#include <strings.h> | ||||||
|  |  #include <ctype.h> | ||||||
|  |  #include <unistd.h> | ||||||
|  |  #include <stdarg.h> | ||||||
|  | --- a/tools/perf/pmu-events/json.c | ||||||
|  | +++ b/tools/perf/pmu-events/json.c | ||||||
|  | @@ -38,7 +38,6 @@ | ||||||
|  |  #include <unistd.h> | ||||||
|  |  #include "jsmn.h" | ||||||
|  |  #include "json.h" | ||||||
|  | -#include <linux/kernel.h> | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  static char *mapfile(const char *fn, size_t *size) | ||||||
| @@ -0,0 +1,65 @@ | |||||||
|  | From 48232d3d931c95953ce2ddfe7da7bb164aef6a73 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Fri, 7 Jul 2017 17:03:16 +0200 | ||||||
|  | Subject: linux-3.6: fix portability of some includes files in tools/ used on the host | ||||||
|  |  | ||||||
|  | lede-commit: 6040b1d29ab1f047c5e49b748abcb6a3196add28 | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  tools/include/tools/be_byteshift.h |  4 ++++ | ||||||
|  |  tools/include/tools/le_byteshift.h |  4 ++++ | ||||||
|  |  tools/include/tools/linux_types.h  | 22 ++++++++++++++++++++++ | ||||||
|  |  3 files changed, 30 insertions(+) | ||||||
|  |  create mode 100644 tools/include/tools/linux_types.h | ||||||
|  |  | ||||||
|  | --- a/tools/include/tools/be_byteshift.h | ||||||
|  | +++ b/tools/include/tools/be_byteshift.h | ||||||
|  | @@ -2,6 +2,10 @@ | ||||||
|  |  #ifndef _TOOLS_BE_BYTESHIFT_H | ||||||
|  |  #define _TOOLS_BE_BYTESHIFT_H | ||||||
|  |   | ||||||
|  | +#ifndef __linux__ | ||||||
|  | +#include "linux_types.h" | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  |  #include <stdint.h> | ||||||
|  |   | ||||||
|  |  static inline uint16_t __get_unaligned_be16(const uint8_t *p) | ||||||
|  | --- a/tools/include/tools/le_byteshift.h | ||||||
|  | +++ b/tools/include/tools/le_byteshift.h | ||||||
|  | @@ -2,6 +2,10 @@ | ||||||
|  |  #ifndef _TOOLS_LE_BYTESHIFT_H | ||||||
|  |  #define _TOOLS_LE_BYTESHIFT_H | ||||||
|  |   | ||||||
|  | +#ifndef __linux__ | ||||||
|  | +#include "linux_types.h" | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  |  #include <stdint.h> | ||||||
|  |   | ||||||
|  |  static inline uint16_t __get_unaligned_le16(const uint8_t *p) | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/tools/include/tools/linux_types.h | ||||||
|  | @@ -0,0 +1,22 @@ | ||||||
|  | +#ifndef __LINUX_TYPES_H | ||||||
|  | +#define __LINUX_TYPES_H | ||||||
|  | + | ||||||
|  | +#include <stdint.h> | ||||||
|  | + | ||||||
|  | +typedef uint8_t __u8; | ||||||
|  | +typedef uint8_t __be8; | ||||||
|  | +typedef uint8_t __le8; | ||||||
|  | + | ||||||
|  | +typedef uint16_t __u16; | ||||||
|  | +typedef uint16_t __be16; | ||||||
|  | +typedef uint16_t __le16; | ||||||
|  | + | ||||||
|  | +typedef uint32_t __u32; | ||||||
|  | +typedef uint32_t __be32; | ||||||
|  | +typedef uint32_t __le32; | ||||||
|  | + | ||||||
|  | +typedef uint64_t __u64; | ||||||
|  | +typedef uint64_t __be64; | ||||||
|  | +typedef uint64_t __le64; | ||||||
|  | + | ||||||
|  | +#endif | ||||||
| @@ -0,0 +1,24 @@ | |||||||
|  | From be9be95ff10e16a5b4ad36f903978d0cc5747024 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Fri, 7 Jul 2017 17:04:08 +0200 | ||||||
|  | Subject: kernel: fix linux/spi/spidev.h portability issues with musl | ||||||
|  |  | ||||||
|  | Felix will try to get this define included into musl | ||||||
|  |  | ||||||
|  | lede-commit: 795e7cf60de19e7a076a46874fab7bb88b43bbff | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  include/uapi/linux/spi/spidev.h | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/include/uapi/linux/spi/spidev.h | ||||||
|  | +++ b/include/uapi/linux/spi/spidev.h | ||||||
|  | @@ -113,7 +113,7 @@ struct spi_ioc_transfer { | ||||||
|  |   | ||||||
|  |  /* not all platforms use <asm-generic/ioctl.h> or _IOC_TYPECHECK() ... */ | ||||||
|  |  #define SPI_MSGSIZE(N) \ | ||||||
|  | -	((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \ | ||||||
|  | +	((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << 13)) \ | ||||||
|  |  		? ((N)*(sizeof (struct spi_ioc_transfer))) : 0) | ||||||
|  |  #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)]) | ||||||
|  |   | ||||||
							
								
								
									
										258
									
								
								target/linux/generic/hack-4.14/220-gc_sections.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										258
									
								
								target/linux/generic/hack-4.14/220-gc_sections.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,258 @@ | |||||||
|  | From e3d8676f5722b7622685581e06e8f53e6138e3ab Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Sat, 15 Jul 2017 23:42:36 +0200 | ||||||
|  | Subject: use -ffunction-sections, -fdata-sections and --gc-sections | ||||||
|  |  | ||||||
|  | In combination with kernel symbol export stripping this significantly reduces | ||||||
|  | the kernel image size. Used on both ARM and MIPS architectures. | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Signed-off-by: Jonas Gorski <jogo@openwrt.org> | ||||||
|  | Signed-off-by: Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | --- | ||||||
|  |  Makefile                          | 10 +++---- | ||||||
|  |  arch/arm/Kconfig                  |  1 + | ||||||
|  |  arch/arm/boot/compressed/Makefile |  1 + | ||||||
|  |  arch/arm/kernel/vmlinux.lds.S     | 26 ++++++++-------- | ||||||
|  |  arch/mips/Kconfig                 |  1 + | ||||||
|  |  arch/mips/kernel/vmlinux.lds.S    |  4 +-- | ||||||
|  |  include/asm-generic/vmlinux.lds.h | 63 ++++++++++++++++++++------------------- | ||||||
|  |  7 files changed, 55 insertions(+), 51 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/Makefile | ||||||
|  | +++ b/Makefile | ||||||
|  | @@ -410,6 +410,11 @@ KBUILD_AFLAGS_MODULE  := -DMODULE | ||||||
|  |  KBUILD_CFLAGS_MODULE  := -DMODULE | ||||||
|  |  KBUILD_LDFLAGS_MODULE = -T $(srctree)/scripts/module-common.lds $(if $(CONFIG_PROFILING),,-s) | ||||||
|  |   | ||||||
|  | +ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION | ||||||
|  | +KBUILD_CFLAGS_KERNEL	+= $(call cc-option,-ffunction-sections,) | ||||||
|  | +KBUILD_CFLAGS_KERNEL	+= $(call cc-option,-fdata-sections,) | ||||||
|  | +endif | ||||||
|  | + | ||||||
|  |  # Read KERNELRELEASE from include/config/kernel.release (if it exists) | ||||||
|  |  KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null) | ||||||
|  |  KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION) | ||||||
|  | @@ -783,11 +788,6 @@ ifdef CONFIG_DEBUG_SECTION_MISMATCH | ||||||
|  |  KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once) | ||||||
|  |  endif | ||||||
|  |   | ||||||
|  | -ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION | ||||||
|  | -KBUILD_CFLAGS	+= $(call cc-option,-ffunction-sections,) | ||||||
|  | -KBUILD_CFLAGS	+= $(call cc-option,-fdata-sections,) | ||||||
|  | -endif | ||||||
|  | - | ||||||
|  |  # arch Makefile may override CC so keep this after arch Makefile is included | ||||||
|  |  NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) | ||||||
|  |  CHECKFLAGS     += $(NOSTDINC_FLAGS) | ||||||
|  | --- a/arch/arm/Kconfig | ||||||
|  | +++ b/arch/arm/Kconfig | ||||||
|  | @@ -91,6 +91,7 @@ config ARM | ||||||
|  |  	select HAVE_UID16 | ||||||
|  |  	select HAVE_VIRT_CPU_ACCOUNTING_GEN | ||||||
|  |  	select IRQ_FORCED_THREADING | ||||||
|  | +	select LD_DEAD_CODE_DATA_ELIMINATION | ||||||
|  |  	select MODULES_USE_ELF_REL | ||||||
|  |  	select NO_BOOTMEM | ||||||
|  |  	select OF_EARLY_FLATTREE if OF | ||||||
|  | --- a/arch/arm/boot/compressed/Makefile | ||||||
|  | +++ b/arch/arm/boot/compressed/Makefile | ||||||
|  | @@ -103,6 +103,7 @@ ifeq ($(CONFIG_FUNCTION_TRACER),y) | ||||||
|  |  ORIG_CFLAGS := $(KBUILD_CFLAGS) | ||||||
|  |  KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) | ||||||
|  |  endif | ||||||
|  | +KBUILD_CFLAGS_KERNEL := $(patsubst -f%-sections,,$(KBUILD_CFLAGS_KERNEL)) | ||||||
|  |   | ||||||
|  |  # -fstack-protector-strong triggers protection checks in this code, | ||||||
|  |  # but it is being used too early to link to meaningful stack_chk logic. | ||||||
|  | --- a/arch/arm/kernel/vmlinux.lds.S | ||||||
|  | +++ b/arch/arm/kernel/vmlinux.lds.S | ||||||
|  | @@ -18,7 +18,7 @@ | ||||||
|  |  #define PROC_INFO							\ | ||||||
|  |  	. = ALIGN(4);							\ | ||||||
|  |  	VMLINUX_SYMBOL(__proc_info_begin) = .;				\ | ||||||
|  | -	*(.proc.info.init)						\ | ||||||
|  | +	KEEP(*(.proc.info.init))					\ | ||||||
|  |  	VMLINUX_SYMBOL(__proc_info_end) = .; | ||||||
|  |   | ||||||
|  |  #define HYPERVISOR_TEXT							\ | ||||||
|  | @@ -29,11 +29,11 @@ | ||||||
|  |  #define IDMAP_TEXT							\ | ||||||
|  |  	ALIGN_FUNCTION();						\ | ||||||
|  |  	VMLINUX_SYMBOL(__idmap_text_start) = .;				\ | ||||||
|  | -	*(.idmap.text)							\ | ||||||
|  | +	KEEP(*(.idmap.text))						\ | ||||||
|  |  	VMLINUX_SYMBOL(__idmap_text_end) = .;				\ | ||||||
|  |  	. = ALIGN(PAGE_SIZE);						\ | ||||||
|  |  	VMLINUX_SYMBOL(__hyp_idmap_text_start) = .;			\ | ||||||
|  | -	*(.hyp.idmap.text)						\ | ||||||
|  | +	KEEP(*(.hyp.idmap.text))					\ | ||||||
|  |  	VMLINUX_SYMBOL(__hyp_idmap_text_end) = .; | ||||||
|  |   | ||||||
|  |  #ifdef CONFIG_HOTPLUG_CPU | ||||||
|  | @@ -106,7 +106,7 @@ SECTIONS | ||||||
|  |  		_stext = .;		/* Text and read-only data	*/ | ||||||
|  |  			IDMAP_TEXT | ||||||
|  |  			__exception_text_start = .; | ||||||
|  | -			*(.exception.text) | ||||||
|  | +			KEEP(*(.exception.text)) | ||||||
|  |  			__exception_text_end = .; | ||||||
|  |  			IRQENTRY_TEXT | ||||||
|  |  			SOFTIRQENTRY_TEXT | ||||||
|  | @@ -135,7 +135,7 @@ SECTIONS | ||||||
|  |  	__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { | ||||||
|  |  		__start___ex_table = .; | ||||||
|  |  #ifdef CONFIG_MMU | ||||||
|  | -		*(__ex_table) | ||||||
|  | +		KEEP(*(__ex_table)) | ||||||
|  |  #endif | ||||||
|  |  		__stop___ex_table = .; | ||||||
|  |  	} | ||||||
|  | @@ -147,12 +147,12 @@ SECTIONS | ||||||
|  |  	. = ALIGN(8); | ||||||
|  |  	.ARM.unwind_idx : { | ||||||
|  |  		__start_unwind_idx = .; | ||||||
|  | -		*(.ARM.exidx*) | ||||||
|  | +		KEEP(*(.ARM.exidx*)) | ||||||
|  |  		__stop_unwind_idx = .; | ||||||
|  |  	} | ||||||
|  |  	.ARM.unwind_tab : { | ||||||
|  |  		__start_unwind_tab = .; | ||||||
|  | -		*(.ARM.extab*) | ||||||
|  | +		KEEP(*(.ARM.extab*)) | ||||||
|  |  		__stop_unwind_tab = .; | ||||||
|  |  	} | ||||||
|  |  #endif | ||||||
|  | @@ -172,14 +172,14 @@ SECTIONS | ||||||
|  |  	 */ | ||||||
|  |  	__vectors_start = .; | ||||||
|  |  	.vectors 0xffff0000 : AT(__vectors_start) { | ||||||
|  | -		*(.vectors) | ||||||
|  | +		KEEP(*(.vectors)) | ||||||
|  |  	} | ||||||
|  |  	. = __vectors_start + SIZEOF(.vectors); | ||||||
|  |  	__vectors_end = .; | ||||||
|  |   | ||||||
|  |  	__stubs_start = .; | ||||||
|  |  	.stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) { | ||||||
|  | -		*(.stubs) | ||||||
|  | +		KEEP(*(.stubs)) | ||||||
|  |  	} | ||||||
|  |  	. = __stubs_start + SIZEOF(.stubs); | ||||||
|  |  	__stubs_end = .; | ||||||
|  | @@ -195,24 +195,24 @@ SECTIONS | ||||||
|  |  	} | ||||||
|  |  	.init.arch.info : { | ||||||
|  |  		__arch_info_begin = .; | ||||||
|  | -		*(.arch.info.init) | ||||||
|  | +		KEEP(*(.arch.info.init)) | ||||||
|  |  		__arch_info_end = .; | ||||||
|  |  	} | ||||||
|  |  	.init.tagtable : { | ||||||
|  |  		__tagtable_begin = .; | ||||||
|  | -		*(.taglist.init) | ||||||
|  | +		KEEP(*(.taglist.init)) | ||||||
|  |  		__tagtable_end = .; | ||||||
|  |  	} | ||||||
|  |  #ifdef CONFIG_SMP_ON_UP | ||||||
|  |  	.init.smpalt : { | ||||||
|  |  		__smpalt_begin = .; | ||||||
|  | -		*(.alt.smp.init) | ||||||
|  | +		KEEP(*(.alt.smp.init)) | ||||||
|  |  		__smpalt_end = .; | ||||||
|  |  	} | ||||||
|  |  #endif | ||||||
|  |  	.init.pv_table : { | ||||||
|  |  		__pv_table_begin = .; | ||||||
|  | -		*(.pv_table) | ||||||
|  | +		KEEP(*(.pv_table)) | ||||||
|  |  		__pv_table_end = .; | ||||||
|  |  	} | ||||||
|  |  	.init.data : { | ||||||
|  | --- a/arch/mips/Kconfig | ||||||
|  | +++ b/arch/mips/Kconfig | ||||||
|  | @@ -39,6 +39,7 @@ config MIPS | ||||||
|  |  	select HAVE_CBPF_JIT if (!64BIT && !CPU_MICROMIPS) | ||||||
|  |  	select HAVE_EBPF_JIT if (64BIT && !CPU_MICROMIPS) | ||||||
|  |  	select HAVE_CC_STACKPROTECTOR | ||||||
|  | +	select LD_DEAD_CODE_DATA_ELIMINATION | ||||||
|  |  	select HAVE_CONTEXT_TRACKING | ||||||
|  |  	select HAVE_COPY_THREAD_TLS | ||||||
|  |  	select HAVE_C_RECORDMCOUNT | ||||||
|  | --- a/arch/mips/kernel/vmlinux.lds.S | ||||||
|  | +++ b/arch/mips/kernel/vmlinux.lds.S | ||||||
|  | @@ -72,7 +72,7 @@ SECTIONS | ||||||
|  |  	/* Exception table for data bus errors */ | ||||||
|  |  	__dbe_table : { | ||||||
|  |  		__start___dbe_table = .; | ||||||
|  | -		*(__dbe_table) | ||||||
|  | +		KEEP(*(__dbe_table)) | ||||||
|  |  		__stop___dbe_table = .; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | @@ -123,7 +123,7 @@ SECTIONS | ||||||
|  |  	. = ALIGN(4); | ||||||
|  |  	.mips.machines.init : AT(ADDR(.mips.machines.init) - LOAD_OFFSET) { | ||||||
|  |  		__mips_machines_start = .; | ||||||
|  | -		*(.mips.machines.init) | ||||||
|  | +		KEEP(*(.mips.machines.init)) | ||||||
|  |  		__mips_machines_end = .; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | --- a/include/asm-generic/vmlinux.lds.h | ||||||
|  | +++ b/include/asm-generic/vmlinux.lds.h | ||||||
|  | @@ -105,7 +105,7 @@ | ||||||
|  |  #ifdef CONFIG_FTRACE_MCOUNT_RECORD | ||||||
|  |  #define MCOUNT_REC()	. = ALIGN(8);				\ | ||||||
|  |  			VMLINUX_SYMBOL(__start_mcount_loc) = .; \ | ||||||
|  | -			*(__mcount_loc)				\ | ||||||
|  | +			KEEP(*(__mcount_loc))			\ | ||||||
|  |  			VMLINUX_SYMBOL(__stop_mcount_loc) = .; | ||||||
|  |  #else | ||||||
|  |  #define MCOUNT_REC() | ||||||
|  | @@ -113,7 +113,7 @@ | ||||||
|  |   | ||||||
|  |  #ifdef CONFIG_TRACE_BRANCH_PROFILING | ||||||
|  |  #define LIKELY_PROFILE()	VMLINUX_SYMBOL(__start_annotated_branch_profile) = .; \ | ||||||
|  | -				*(_ftrace_annotated_branch)			      \ | ||||||
|  | +				KEEP(*(_ftrace_annotated_branch))		      \ | ||||||
|  |  				VMLINUX_SYMBOL(__stop_annotated_branch_profile) = .; | ||||||
|  |  #else | ||||||
|  |  #define LIKELY_PROFILE() | ||||||
|  | @@ -121,7 +121,7 @@ | ||||||
|  |   | ||||||
|  |  #ifdef CONFIG_PROFILE_ALL_BRANCHES | ||||||
|  |  #define BRANCH_PROFILE()	VMLINUX_SYMBOL(__start_branch_profile) = .;   \ | ||||||
|  | -				*(_ftrace_branch)			      \ | ||||||
|  | +				KEEP(*(_ftrace_branch))			      \ | ||||||
|  |  				VMLINUX_SYMBOL(__stop_branch_profile) = .; | ||||||
|  |  #else | ||||||
|  |  #define BRANCH_PROFILE() | ||||||
|  | @@ -237,7 +237,8 @@ | ||||||
|  |  	LIKELY_PROFILE()		       				\ | ||||||
|  |  	BRANCH_PROFILE()						\ | ||||||
|  |  	TRACE_PRINTKS()							\ | ||||||
|  | -	TRACEPOINT_STR() | ||||||
|  | +	TRACEPOINT_STR()                                                \ | ||||||
|  | +	*(.data.[a-zA-Z_]*) | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  |   * Data section helpers | ||||||
|  | @@ -496,7 +497,7 @@ | ||||||
|  |  #define ENTRY_TEXT							\ | ||||||
|  |  		ALIGN_FUNCTION();					\ | ||||||
|  |  		VMLINUX_SYMBOL(__entry_text_start) = .;			\ | ||||||
|  | -		*(.entry.text)						\ | ||||||
|  | +		KEEP(*(.entry.text))					\ | ||||||
|  |  		VMLINUX_SYMBOL(__entry_text_end) = .; | ||||||
|  |   | ||||||
|  |  #define IRQENTRY_TEXT							\ | ||||||
|  | @@ -603,7 +604,7 @@ | ||||||
|  |  	. = ALIGN(sbss_align);						\ | ||||||
|  |  	.sbss : AT(ADDR(.sbss) - LOAD_OFFSET) {				\ | ||||||
|  |  		*(.dynsbss)						\ | ||||||
|  | -		*(.sbss)						\ | ||||||
|  | +		*(.sbss .sbss.*)					\ | ||||||
|  |  		*(.scommon)						\ | ||||||
|  |  	} | ||||||
|  |   | ||||||
							
								
								
									
										101
									
								
								target/linux/generic/hack-4.14/221-module_exports.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								target/linux/generic/hack-4.14/221-module_exports.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | |||||||
|  | From b14784e7883390c20ed3ff904892255404a5914b Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Fri, 7 Jul 2017 17:05:53 +0200 | ||||||
|  | Subject: add an optional config option for stripping all unnecessary symbol exports from the kernel image | ||||||
|  |  | ||||||
|  | lede-commit: bb5a40c64b7c4f4848509fa0a6625055fc9e66cc | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  include/asm-generic/vmlinux.lds.h | 18 +++++++++++++++--- | ||||||
|  |  include/linux/export.h            |  9 ++++++++- | ||||||
|  |  scripts/Makefile.build            |  2 +- | ||||||
|  |  3 files changed, 24 insertions(+), 5 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/include/asm-generic/vmlinux.lds.h | ||||||
|  | +++ b/include/asm-generic/vmlinux.lds.h | ||||||
|  | @@ -54,6 +54,16 @@ | ||||||
|  |  #define LOAD_OFFSET 0 | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  | +#ifndef SYMTAB_KEEP | ||||||
|  | +#define SYMTAB_KEEP KEEP(*(SORT(___ksymtab+*))) | ||||||
|  | +#define SYMTAB_KEEP_GPL KEEP(*(SORT(___ksymtab_gpl+*))) | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  | +#ifndef SYMTAB_DISCARD | ||||||
|  | +#define SYMTAB_DISCARD | ||||||
|  | +#define SYMTAB_DISCARD_GPL | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  |  #include <linux/export.h> | ||||||
|  |   | ||||||
|  |  /* Align . to a 8 byte boundary equals to maximum function alignment. */ | ||||||
|  | @@ -341,14 +351,14 @@ | ||||||
|  |  	/* Kernel symbol table: Normal symbols */			\ | ||||||
|  |  	__ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {		\ | ||||||
|  |  		VMLINUX_SYMBOL(__start___ksymtab) = .;			\ | ||||||
|  | -		KEEP(*(SORT(___ksymtab+*)))				\ | ||||||
|  | +		SYMTAB_KEEP						\ | ||||||
|  |  		VMLINUX_SYMBOL(__stop___ksymtab) = .;			\ | ||||||
|  |  	}								\ | ||||||
|  |  									\ | ||||||
|  |  	/* Kernel symbol table: GPL-only symbols */			\ | ||||||
|  |  	__ksymtab_gpl     : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) {	\ | ||||||
|  |  		VMLINUX_SYMBOL(__start___ksymtab_gpl) = .;		\ | ||||||
|  | -		KEEP(*(SORT(___ksymtab_gpl+*)))				\ | ||||||
|  | +		SYMTAB_KEEP_GPL						\ | ||||||
|  |  		VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .;		\ | ||||||
|  |  	}								\ | ||||||
|  |  									\ | ||||||
|  | @@ -410,7 +420,7 @@ | ||||||
|  |  									\ | ||||||
|  |  	/* Kernel symbol table: strings */				\ | ||||||
|  |          __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {	\ | ||||||
|  | -		*(__ksymtab_strings)					\ | ||||||
|  | +		*(__ksymtab_strings+*)					\ | ||||||
|  |  	}								\ | ||||||
|  |  									\ | ||||||
|  |  	/* __*init sections */						\ | ||||||
|  | @@ -793,6 +803,8 @@ | ||||||
|  |  	EXIT_TEXT							\ | ||||||
|  |  	EXIT_DATA							\ | ||||||
|  |  	EXIT_CALL							\ | ||||||
|  | +	SYMTAB_DISCARD							\ | ||||||
|  | +	SYMTAB_DISCARD_GPL						\ | ||||||
|  |  	*(.discard)							\ | ||||||
|  |  	*(.discard.*)							\ | ||||||
|  |  	} | ||||||
|  | --- a/include/linux/export.h | ||||||
|  | +++ b/include/linux/export.h | ||||||
|  | @@ -60,12 +60,19 @@ extern struct module __this_module; | ||||||
|  |  #define __CRC_SYMBOL(sym, sec) | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  | +#ifdef MODULE | ||||||
|  | +#define __EXPORT_SUFFIX(sym) | ||||||
|  | +#else | ||||||
|  | +#define __EXPORT_SUFFIX(sym) "+" #sym | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  |  /* For every exported symbol, place a struct in the __ksymtab section */ | ||||||
|  |  #define ___EXPORT_SYMBOL(sym, sec)					\ | ||||||
|  |  	extern typeof(sym) sym;						\ | ||||||
|  |  	__CRC_SYMBOL(sym, sec)						\ | ||||||
|  |  	static const char __kstrtab_##sym[]				\ | ||||||
|  | -	__attribute__((section("__ksymtab_strings"), aligned(1)))	\ | ||||||
|  | +	__attribute__((section("__ksymtab_strings"			\ | ||||||
|  | +	  __EXPORT_SUFFIX(sym)), aligned(1)))				\ | ||||||
|  |  	= VMLINUX_SYMBOL_STR(sym);					\ | ||||||
|  |  	static const struct kernel_symbol __ksymtab_##sym		\ | ||||||
|  |  	__used								\ | ||||||
|  | --- a/scripts/Makefile.build | ||||||
|  | +++ b/scripts/Makefile.build | ||||||
|  | @@ -420,7 +420,7 @@ targets += $(extra-y) $(MAKECMDGOALS) $( | ||||||
|  |  # Linker scripts preprocessor (.lds.S -> .lds) | ||||||
|  |  # --------------------------------------------------------------------------- | ||||||
|  |  quiet_cmd_cpp_lds_S = LDS     $@ | ||||||
|  | -      cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -U$(ARCH) \ | ||||||
|  | +      cmd_cpp_lds_S = $(CPP) $(EXTRA_LDSFLAGS) $(cpp_flags) -P -U$(ARCH) \ | ||||||
|  |  	                     -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $< | ||||||
|  |   | ||||||
|  |  $(obj)/%.lds: $(src)/%.lds.S FORCE | ||||||
| @@ -0,0 +1,71 @@ | |||||||
|  | From b3d00b452467f621317953d9e4c6f9ae8dcfd271 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Imre Kaloz <kaloz@openwrt.org> | ||||||
|  | Date: Fri, 7 Jul 2017 17:06:55 +0200 | ||||||
|  | Subject: use the openwrt lzma options for now | ||||||
|  |  | ||||||
|  | lede-commit: 548de949f392049420a6a1feeef118b30ab8ea8c | ||||||
|  | Signed-off-by: Imre Kaloz <kaloz@openwrt.org> | ||||||
|  | --- | ||||||
|  |  lib/decompress.c              |  1 + | ||||||
|  |  scripts/Makefile.lib          |  2 +- | ||||||
|  |  scripts/gen_initramfs_list.sh | 10 +++++----- | ||||||
|  |  3 files changed, 7 insertions(+), 6 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/lib/decompress.c | ||||||
|  | +++ b/lib/decompress.c | ||||||
|  | @@ -49,6 +49,7 @@ static const struct compress_format comp | ||||||
|  |  	{ {0x1f, 0x9e}, "gzip", gunzip }, | ||||||
|  |  	{ {0x42, 0x5a}, "bzip2", bunzip2 }, | ||||||
|  |  	{ {0x5d, 0x00}, "lzma", unlzma }, | ||||||
|  | +	{ {0x6d, 0x00}, "lzma-openwrt", unlzma }, | ||||||
|  |  	{ {0xfd, 0x37}, "xz", unxz }, | ||||||
|  |  	{ {0x89, 0x4c}, "lzo", unlzo }, | ||||||
|  |  	{ {0x02, 0x21}, "lz4", unlz4 }, | ||||||
|  | --- a/scripts/Makefile.lib | ||||||
|  | +++ b/scripts/Makefile.lib | ||||||
|  | @@ -348,7 +348,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^) | ||||||
|  |   | ||||||
|  |  quiet_cmd_lzma = LZMA    $@ | ||||||
|  |  cmd_lzma = (cat $(filter-out FORCE,$^) | \ | ||||||
|  | -	lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ | ||||||
|  | +	lzma e -d20 -lc1 -lp2 -pb2 -eos -si -so && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ | ||||||
|  |  	(rm -f $@ ; false) | ||||||
|  |   | ||||||
|  |  quiet_cmd_lzo = LZO     $@ | ||||||
|  | --- a/scripts/gen_initramfs_list.sh | ||||||
|  | +++ b/scripts/gen_initramfs_list.sh | ||||||
|  | @@ -229,7 +229,7 @@ cpio_list= | ||||||
|  |  output="/dev/stdout" | ||||||
|  |  output_file="" | ||||||
|  |  is_cpio_compressed= | ||||||
|  | -compr="gzip -n -9 -f" | ||||||
|  | +compr="gzip -n -9 -f -" | ||||||
|  |   | ||||||
|  |  arg="$1" | ||||||
|  |  case "$arg" in | ||||||
|  | @@ -245,13 +245,13 @@ case "$arg" in | ||||||
|  |  		output=${cpio_list} | ||||||
|  |  		echo "$output_file" | grep -q "\.gz$" \ | ||||||
|  |                  && [ -x "`which gzip 2> /dev/null`" ] \ | ||||||
|  | -                && compr="gzip -n -9 -f" | ||||||
|  | +                && compr="gzip -n -9 -f -" | ||||||
|  |  		echo "$output_file" | grep -q "\.bz2$" \ | ||||||
|  |                  && [ -x "`which bzip2 2> /dev/null`" ] \ | ||||||
|  | -                && compr="bzip2 -9 -f" | ||||||
|  | +                && compr="bzip2 -9 -f -" | ||||||
|  |  		echo "$output_file" | grep -q "\.lzma$" \ | ||||||
|  |                  && [ -x "`which lzma 2> /dev/null`" ] \ | ||||||
|  | -                && compr="lzma -9 -f" | ||||||
|  | +                && compr="lzma e -d20 -lc1 -lp2 -pb2 -eos -si -so" | ||||||
|  |  		echo "$output_file" | grep -q "\.xz$" \ | ||||||
|  |                  && [ -x "`which xz 2> /dev/null`" ] \ | ||||||
|  |                  && compr="xz --check=crc32 --lzma2=dict=1MiB" | ||||||
|  | @@ -320,7 +320,7 @@ if [ ! -z ${output_file} ]; then | ||||||
|  |  	if [ "${is_cpio_compressed}" = "compressed" ]; then | ||||||
|  |  		cat ${cpio_tfile} > ${output_file} | ||||||
|  |  	else | ||||||
|  | -		(cat ${cpio_tfile} | ${compr}  - > ${output_file}) \ | ||||||
|  | +		(cat ${cpio_tfile} | ${compr} > ${output_file}) \ | ||||||
|  |  		|| (rm -f ${output_file} ; false) | ||||||
|  |  	fi | ||||||
|  |  	[ -z ${cpio_file} ] && rm ${cpio_tfile} | ||||||
							
								
								
									
										27
									
								
								target/linux/generic/hack-4.14/250-netfilter_depends.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								target/linux/generic/hack-4.14/250-netfilter_depends.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: hack: net: remove bogus netfilter dependencies | ||||||
|  |  | ||||||
|  | lede-commit: 589d2a377dee27d206fc3725325309cf649e4df6 | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  net/netfilter/Kconfig | 2 -- | ||||||
|  |  1 file changed, 2 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/net/netfilter/Kconfig | ||||||
|  | +++ b/net/netfilter/Kconfig | ||||||
|  | @@ -223,7 +223,6 @@ config NF_CONNTRACK_FTP | ||||||
|  |   | ||||||
|  |  config NF_CONNTRACK_H323 | ||||||
|  |  	tristate "H.323 protocol support" | ||||||
|  | -	depends on IPV6 || IPV6=n | ||||||
|  |  	depends on NETFILTER_ADVANCED | ||||||
|  |  	help | ||||||
|  |  	  H.323 is a VoIP signalling protocol from ITU-T. As one of the most | ||||||
|  | @@ -1012,7 +1011,6 @@ config NETFILTER_XT_TARGET_SECMARK | ||||||
|  |   | ||||||
|  |  config NETFILTER_XT_TARGET_TCPMSS | ||||||
|  |  	tristate '"TCPMSS" target support' | ||||||
|  | -	depends on IPV6 || IPV6=n | ||||||
|  |  	default m if NETFILTER_ADVANCED=n | ||||||
|  |  	---help--- | ||||||
|  |  	  This option adds a `TCPMSS' target, which allows you to alter the | ||||||
							
								
								
									
										197
									
								
								target/linux/generic/hack-4.14/251-sound_kconfig.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								target/linux/generic/hack-4.14/251-sound_kconfig.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,197 @@ | |||||||
|  | From da3c50704f14132f4adf80d48e9a4cd5d46e54c9 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: John Crispin <john@phrozen.org> | ||||||
|  | Date: Fri, 7 Jul 2017 17:09:21 +0200 | ||||||
|  | Subject: kconfig: owrt specifc dependencies | ||||||
|  |  | ||||||
|  | Signed-off-by: John Crispin <john@phrozen.org> | ||||||
|  | --- | ||||||
|  |  crypto/Kconfig        | 10 +++++----- | ||||||
|  |  drivers/bcma/Kconfig  |  1 + | ||||||
|  |  drivers/ssb/Kconfig   |  3 ++- | ||||||
|  |  lib/Kconfig           |  8 ++++---- | ||||||
|  |  net/netfilter/Kconfig |  2 +- | ||||||
|  |  net/wireless/Kconfig  | 17 ++++++++++------- | ||||||
|  |  sound/core/Kconfig    |  4 ++-- | ||||||
|  |  7 files changed, 25 insertions(+), 20 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/crypto/Kconfig | ||||||
|  | +++ b/crypto/Kconfig | ||||||
|  | @@ -33,7 +33,7 @@ config CRYPTO_FIPS | ||||||
|  |  	  this is. | ||||||
|  |   | ||||||
|  |  config CRYPTO_ALGAPI | ||||||
|  | -	tristate | ||||||
|  | +	tristate "ALGAPI" | ||||||
|  |  	select CRYPTO_ALGAPI2 | ||||||
|  |  	help | ||||||
|  |  	  This option provides the API for cryptographic algorithms. | ||||||
|  | @@ -42,7 +42,7 @@ config CRYPTO_ALGAPI2 | ||||||
|  |  	tristate | ||||||
|  |   | ||||||
|  |  config CRYPTO_AEAD | ||||||
|  | -	tristate | ||||||
|  | +	tristate "AEAD" | ||||||
|  |  	select CRYPTO_AEAD2 | ||||||
|  |  	select CRYPTO_ALGAPI | ||||||
|  |   | ||||||
|  | @@ -53,7 +53,7 @@ config CRYPTO_AEAD2 | ||||||
|  |  	select CRYPTO_RNG2 | ||||||
|  |   | ||||||
|  |  config CRYPTO_BLKCIPHER | ||||||
|  | -	tristate | ||||||
|  | +	tristate "BLKCIPHER" | ||||||
|  |  	select CRYPTO_BLKCIPHER2 | ||||||
|  |  	select CRYPTO_ALGAPI | ||||||
|  |   | ||||||
|  | @@ -64,7 +64,7 @@ config CRYPTO_BLKCIPHER2 | ||||||
|  |  	select CRYPTO_WORKQUEUE | ||||||
|  |   | ||||||
|  |  config CRYPTO_HASH | ||||||
|  | -	tristate | ||||||
|  | +	tristate "HASH" | ||||||
|  |  	select CRYPTO_HASH2 | ||||||
|  |  	select CRYPTO_ALGAPI | ||||||
|  |   | ||||||
|  | @@ -73,7 +73,7 @@ config CRYPTO_HASH2 | ||||||
|  |  	select CRYPTO_ALGAPI2 | ||||||
|  |   | ||||||
|  |  config CRYPTO_RNG | ||||||
|  | -	tristate | ||||||
|  | +	tristate "RNG" | ||||||
|  |  	select CRYPTO_RNG2 | ||||||
|  |  	select CRYPTO_ALGAPI | ||||||
|  |   | ||||||
|  | --- a/drivers/bcma/Kconfig | ||||||
|  | +++ b/drivers/bcma/Kconfig | ||||||
|  | @@ -15,6 +15,7 @@ menuconfig BCMA | ||||||
|  |  config BCMA_BLOCKIO | ||||||
|  |  	bool | ||||||
|  |  	depends on BCMA | ||||||
|  | +	default y | ||||||
|  |   | ||||||
|  |  config BCMA_HOST_PCI_POSSIBLE | ||||||
|  |  	bool | ||||||
|  | --- a/drivers/ssb/Kconfig | ||||||
|  | +++ b/drivers/ssb/Kconfig | ||||||
|  | @@ -29,6 +29,7 @@ config SSB_SPROM | ||||||
|  |  config SSB_BLOCKIO | ||||||
|  |  	bool | ||||||
|  |  	depends on SSB | ||||||
|  | +	default y | ||||||
|  |   | ||||||
|  |  config SSB_PCIHOST_POSSIBLE | ||||||
|  |  	bool | ||||||
|  | @@ -49,7 +50,7 @@ config SSB_PCIHOST | ||||||
|  |  config SSB_B43_PCI_BRIDGE | ||||||
|  |  	bool | ||||||
|  |  	depends on SSB_PCIHOST | ||||||
|  | -	default n | ||||||
|  | +	default y | ||||||
|  |   | ||||||
|  |  config SSB_PCMCIAHOST_POSSIBLE | ||||||
|  |  	bool | ||||||
|  | --- a/lib/Kconfig | ||||||
|  | +++ b/lib/Kconfig | ||||||
|  | @@ -358,16 +358,16 @@ config BCH_CONST_T | ||||||
|  |  # Textsearch support is select'ed if needed | ||||||
|  |  # | ||||||
|  |  config TEXTSEARCH | ||||||
|  | -	bool | ||||||
|  | +	boolean	"Textsearch support" | ||||||
|  |   | ||||||
|  |  config TEXTSEARCH_KMP | ||||||
|  | -	tristate | ||||||
|  | +	tristate "Textsearch KMP" | ||||||
|  |   | ||||||
|  |  config TEXTSEARCH_BM | ||||||
|  | -	tristate | ||||||
|  | +	tristate "Textsearch BM" | ||||||
|  |   | ||||||
|  |  config TEXTSEARCH_FSM | ||||||
|  | -	tristate | ||||||
|  | +	tristate "Textsearch FSM" | ||||||
|  |   | ||||||
|  |  config BTREE | ||||||
|  |  	bool | ||||||
|  | --- a/net/netfilter/Kconfig | ||||||
|  | +++ b/net/netfilter/Kconfig | ||||||
|  | @@ -10,7 +10,7 @@ config NETFILTER_INGRESS | ||||||
|  |  	  infrastructure. | ||||||
|  |   | ||||||
|  |  config NETFILTER_NETLINK | ||||||
|  | -	tristate | ||||||
|  | +	tristate "Netfilter NFNETLINK interface" | ||||||
|  |   | ||||||
|  |  config NETFILTER_NETLINK_ACCT | ||||||
|  |  tristate "Netfilter NFACCT over NFNETLINK interface" | ||||||
|  | --- a/net/wireless/Kconfig | ||||||
|  | +++ b/net/wireless/Kconfig | ||||||
|  | @@ -1,5 +1,5 @@ | ||||||
|  |  config WIRELESS_EXT | ||||||
|  | -	bool | ||||||
|  | +	bool "Wireless extensions" | ||||||
|  |   | ||||||
|  |  config WEXT_CORE | ||||||
|  |  	def_bool y | ||||||
|  | @@ -11,10 +11,10 @@ config WEXT_PROC | ||||||
|  |  	depends on WEXT_CORE | ||||||
|  |   | ||||||
|  |  config WEXT_SPY | ||||||
|  | -	bool | ||||||
|  | +	bool "WEXT_SPY" | ||||||
|  |   | ||||||
|  |  config WEXT_PRIV | ||||||
|  | -	bool | ||||||
|  | +	bool "WEXT_PRIV" | ||||||
|  |   | ||||||
|  |  config CFG80211 | ||||||
|  |  	tristate "cfg80211 - wireless configuration API" | ||||||
|  | @@ -188,7 +188,7 @@ config CFG80211_WEXT_EXPORT | ||||||
|  |  	  wext compatibility symbols to be exported. | ||||||
|  |   | ||||||
|  |  config LIB80211 | ||||||
|  | -	tristate | ||||||
|  | +	tristate "LIB80211" | ||||||
|  |  	default n | ||||||
|  |  	help | ||||||
|  |  	  This options enables a library of common routines used | ||||||
|  | @@ -197,13 +197,16 @@ config LIB80211 | ||||||
|  |  	  Drivers should select this themselves if needed. | ||||||
|  |   | ||||||
|  |  config LIB80211_CRYPT_WEP | ||||||
|  | -	tristate | ||||||
|  | +	tristate "LIB80211_CRYPT_WEP" | ||||||
|  | +	select LIB80211 | ||||||
|  |   | ||||||
|  |  config LIB80211_CRYPT_CCMP | ||||||
|  | -	tristate | ||||||
|  | +	tristate "LIB80211_CRYPT_CCMP" | ||||||
|  | +	select LIB80211 | ||||||
|  |   | ||||||
|  |  config LIB80211_CRYPT_TKIP | ||||||
|  | -	tristate | ||||||
|  | +	tristate "LIB80211_CRYPT_TKIP" | ||||||
|  | +	select LIB80211 | ||||||
|  |   | ||||||
|  |  config LIB80211_DEBUG | ||||||
|  |  	bool "lib80211 debugging messages" | ||||||
|  | --- a/sound/core/Kconfig | ||||||
|  | +++ b/sound/core/Kconfig | ||||||
|  | @@ -16,7 +16,7 @@ config SND_DMAENGINE_PCM | ||||||
|  |  	tristate | ||||||
|  |   | ||||||
|  |  config SND_HWDEP | ||||||
|  | -	tristate | ||||||
|  | +	tristate "Sound hardware support" | ||||||
|  |   | ||||||
|  |  config SND_SEQ_DEVICE | ||||||
|  |  	tristate | ||||||
|  | @@ -26,7 +26,7 @@ config SND_RAWMIDI | ||||||
|  |  	select SND_SEQ_DEVICE if SND_SEQUENCER != n | ||||||
|  |   | ||||||
|  |  config SND_COMPRESS_OFFLOAD | ||||||
|  | -	tristate | ||||||
|  | +	tristate "Compression offloading support" | ||||||
|  |   | ||||||
|  |  config SND_JACK | ||||||
|  |  	bool | ||||||
							
								
								
									
										109
									
								
								target/linux/generic/hack-4.14/259-regmap_dynamic.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								target/linux/generic/hack-4.14/259-regmap_dynamic.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | |||||||
|  | From 811d9e2268a62b830cfe93cd8bc929afcb8b198b Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Sat, 15 Jul 2017 21:12:38 +0200 | ||||||
|  | Subject: kernel: move regmap bloat out of the kernel image if it is only being used in modules | ||||||
|  |  | ||||||
|  | lede-commit: 96f39119815028073583e4fca3a9c5fe9141e998 | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  drivers/base/regmap/Kconfig  | 15 ++++++++++----- | ||||||
|  |  drivers/base/regmap/Makefile | 12 ++++++++---- | ||||||
|  |  drivers/base/regmap/regmap.c |  3 +++ | ||||||
|  |  include/linux/regmap.h       |  2 +- | ||||||
|  |  4 files changed, 22 insertions(+), 10 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/base/regmap/Kconfig | ||||||
|  | +++ b/drivers/base/regmap/Kconfig | ||||||
|  | @@ -4,9 +4,8 @@ | ||||||
|  |  # subsystems should select the appropriate symbols. | ||||||
|  |   | ||||||
|  |  config REGMAP | ||||||
|  | -	default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ) | ||||||
|  |  	select IRQ_DOMAIN if REGMAP_IRQ | ||||||
|  | -	bool | ||||||
|  | +	tristate "Regmap" | ||||||
|  |   | ||||||
|  |  config REGCACHE_COMPRESSED | ||||||
|  |  	select LZO_COMPRESS | ||||||
|  | @@ -17,23 +16,30 @@ config REGMAP_AC97 | ||||||
|  |  	tristate | ||||||
|  |   | ||||||
|  |  config REGMAP_I2C | ||||||
|  | -	tristate | ||||||
|  | +	tristate "Regmap I2C" | ||||||
|  | +	select REGMAP | ||||||
|  |  	depends on I2C | ||||||
|  |   | ||||||
|  |  config REGMAP_SPI | ||||||
|  | -	tristate | ||||||
|  | +	tristate "Regmap SPI" | ||||||
|  | +	select REGMAP | ||||||
|  | +	depends on SPI_MASTER | ||||||
|  |  	depends on SPI | ||||||
|  |   | ||||||
|  |  config REGMAP_SPMI | ||||||
|  | +	select REGMAP | ||||||
|  |  	tristate | ||||||
|  |  	depends on SPMI | ||||||
|  |   | ||||||
|  |  config REGMAP_W1 | ||||||
|  | +	select REGMAP | ||||||
|  |  	tristate | ||||||
|  |  	depends on W1 | ||||||
|  |   | ||||||
|  |  config REGMAP_MMIO | ||||||
|  | -	tristate | ||||||
|  | +	tristate "Regmap MMIO" | ||||||
|  | +	select REGMAP | ||||||
|  |   | ||||||
|  |  config REGMAP_IRQ | ||||||
|  | +	select REGMAP | ||||||
|  |  	bool | ||||||
|  | --- a/drivers/base/regmap/Makefile | ||||||
|  | +++ b/drivers/base/regmap/Makefile | ||||||
|  | @@ -2,10 +2,14 @@ | ||||||
|  |  # For include/trace/define_trace.h to include trace.h | ||||||
|  |  CFLAGS_regmap.o := -I$(src) | ||||||
|  |   | ||||||
|  | -obj-$(CONFIG_REGMAP) += regmap.o regcache.o | ||||||
|  | -obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-flat.o | ||||||
|  | -obj-$(CONFIG_REGCACHE_COMPRESSED) += regcache-lzo.o | ||||||
|  | -obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o | ||||||
|  | +regmap-core-objs = regmap.o regcache.o regcache-rbtree.o regcache-flat.o | ||||||
|  | +ifdef CONFIG_DEBUG_FS | ||||||
|  | +regmap-core-objs += regmap-debugfs.o | ||||||
|  | +endif | ||||||
|  | +ifdef CONFIG_REGCACHE_COMPRESSED | ||||||
|  | +regmap-core-objs += regcache-lzo.o | ||||||
|  | +endif | ||||||
|  | +obj-$(CONFIG_REGMAP) += regmap-core.o | ||||||
|  |  obj-$(CONFIG_REGMAP_AC97) += regmap-ac97.o | ||||||
|  |  obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o | ||||||
|  |  obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o | ||||||
|  | --- a/drivers/base/regmap/regmap.c | ||||||
|  | +++ b/drivers/base/regmap/regmap.c | ||||||
|  | @@ -13,6 +13,7 @@ | ||||||
|  |  #include <linux/device.h> | ||||||
|  |  #include <linux/slab.h> | ||||||
|  |  #include <linux/export.h> | ||||||
|  | +#include <linux/module.h> | ||||||
|  |  #include <linux/mutex.h> | ||||||
|  |  #include <linux/err.h> | ||||||
|  |  #include <linux/of.h> | ||||||
|  | @@ -2926,3 +2927,5 @@ static int __init regmap_initcall(void) | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |  postcore_initcall(regmap_initcall); | ||||||
|  | + | ||||||
|  | +MODULE_LICENSE("GPL"); | ||||||
|  | --- a/include/linux/regmap.h | ||||||
|  | +++ b/include/linux/regmap.h | ||||||
|  | @@ -139,7 +139,7 @@ struct reg_sequence { | ||||||
|  |  	pollret ?: ((cond) ? 0 : -ETIMEDOUT); \ | ||||||
|  |  }) | ||||||
|  |   | ||||||
|  | -#ifdef CONFIG_REGMAP | ||||||
|  | +#if IS_ENABLED(CONFIG_REGMAP) | ||||||
|  |   | ||||||
|  |  enum regmap_endian { | ||||||
|  |  	/* Unspecified -> 0 -> Backwards compatible default */ | ||||||
| @@ -0,0 +1,60 @@ | |||||||
|  | From fd1799b0bf5efa46dd3e6dfbbf3955564807e508 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Fri, 7 Jul 2017 17:12:51 +0200 | ||||||
|  | Subject: kernel: prevent cryptomgr from pulling in useless extra dependencies for tests that are not run | ||||||
|  |  | ||||||
|  | Reduces kernel size after LZMA by about 5k on MIPS | ||||||
|  |  | ||||||
|  | lede-commit: 044c316167e076479a344c59905e5b435b84a77f | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  crypto/Kconfig   | 13 ++++++------- | ||||||
|  |  crypto/algboss.c |  4 ++++ | ||||||
|  |  2 files changed, 10 insertions(+), 7 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/crypto/Kconfig | ||||||
|  | +++ b/crypto/Kconfig | ||||||
|  | @@ -143,13 +143,13 @@ config CRYPTO_MANAGER | ||||||
|  |  	  cbc(aes). | ||||||
|  |   | ||||||
|  |  config CRYPTO_MANAGER2 | ||||||
|  | -	def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y) | ||||||
|  | -	select CRYPTO_AEAD2 | ||||||
|  | -	select CRYPTO_HASH2 | ||||||
|  | -	select CRYPTO_BLKCIPHER2 | ||||||
|  | -	select CRYPTO_AKCIPHER2 | ||||||
|  | -	select CRYPTO_KPP2 | ||||||
|  | -	select CRYPTO_ACOMP2 | ||||||
|  | +	def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y && !CRYPTO_MANAGER_DISABLE_TESTS) | ||||||
|  | +	select CRYPTO_AEAD2 if !CRYPTO_MANAGER_DISABLE_TESTS | ||||||
|  | +	select CRYPTO_HASH2 if !CRYPTO_MANAGER_DISABLE_TESTS | ||||||
|  | +	select CRYPTO_BLKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS | ||||||
|  | +	select CRYPTO_AKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS | ||||||
|  | +	select CRYPTO_KPP2 if !CRYPTO_MANAGER_DISABLE_TESTS | ||||||
|  | +	select CRYPTO_ACOMP2 if !CRYPTO_MANAGER_DISABLE_TESTS | ||||||
|  |   | ||||||
|  |  config CRYPTO_USER | ||||||
|  |  	tristate "Userspace cryptographic algorithm configuration" | ||||||
|  | @@ -162,7 +162,6 @@ config CRYPTO_USER | ||||||
|  |  config CRYPTO_MANAGER_DISABLE_TESTS | ||||||
|  |  	bool "Disable run-time self tests" | ||||||
|  |  	default y | ||||||
|  | -	depends on CRYPTO_MANAGER2 | ||||||
|  |  	help | ||||||
|  |  	  Disable run-time self tests that normally take place at | ||||||
|  |  	  algorithm registration. | ||||||
|  | --- a/crypto/algboss.c | ||||||
|  | +++ b/crypto/algboss.c | ||||||
|  | @@ -248,8 +248,12 @@ static int cryptomgr_schedule_test(struc | ||||||
|  |  	type = alg->cra_flags; | ||||||
|  |   | ||||||
|  |  	/* Do not test internal algorithms. */ | ||||||
|  | +#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS | ||||||
|  | +	type |= CRYPTO_ALG_TESTED; | ||||||
|  | +#else | ||||||
|  |  	if (type & CRYPTO_ALG_INTERNAL) | ||||||
|  |  		type |= CRYPTO_ALG_TESTED; | ||||||
|  | +#endif | ||||||
|  |   | ||||||
|  |  	param->type = type; | ||||||
|  |   | ||||||
							
								
								
									
										84
									
								
								target/linux/generic/hack-4.14/280-rfkill-stubs.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								target/linux/generic/hack-4.14/280-rfkill-stubs.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | |||||||
|  | From 236c1acdfef5958010ac9814a9872e0a46fd78ee Mon Sep 17 00:00:00 2001 | ||||||
|  | From: John Crispin <john@phrozen.org> | ||||||
|  | Date: Fri, 7 Jul 2017 17:13:44 +0200 | ||||||
|  | Subject: rfkill: add fake rfkill support | ||||||
|  |  | ||||||
|  | allow building of modules depending on RFKILL even if RFKILL is not enabled. | ||||||
|  |  | ||||||
|  | Signed-off-by: John Crispin <john@phrozen.org> | ||||||
|  | --- | ||||||
|  |  include/linux/rfkill.h |  2 +- | ||||||
|  |  net/Makefile           |  2 +- | ||||||
|  |  net/rfkill/Kconfig     | 14 +++++++++----- | ||||||
|  |  net/rfkill/Makefile    |  2 +- | ||||||
|  |  4 files changed, 12 insertions(+), 8 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/include/linux/rfkill.h | ||||||
|  | +++ b/include/linux/rfkill.h | ||||||
|  | @@ -64,7 +64,7 @@ struct rfkill_ops { | ||||||
|  |  	int	(*set_block)(void *data, bool blocked); | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | -#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) | ||||||
|  | +#if defined(CONFIG_RFKILL_FULL) || defined(CONFIG_RFKILL_FULL_MODULE) | ||||||
|  |  /** | ||||||
|  |   * rfkill_alloc - allocate rfkill structure | ||||||
|  |   * @name: name of the struct -- the string is not copied internally | ||||||
|  | --- a/net/Makefile | ||||||
|  | +++ b/net/Makefile | ||||||
|  | @@ -53,7 +53,7 @@ obj-$(CONFIG_TIPC)		+= tipc/ | ||||||
|  |  obj-$(CONFIG_NETLABEL)		+= netlabel/ | ||||||
|  |  obj-$(CONFIG_IUCV)		+= iucv/ | ||||||
|  |  obj-$(CONFIG_SMC)		+= smc/ | ||||||
|  | -obj-$(CONFIG_RFKILL)		+= rfkill/ | ||||||
|  | +obj-$(CONFIG_RFKILL_FULL)	+= rfkill/ | ||||||
|  |  obj-$(CONFIG_NET_9P)		+= 9p/ | ||||||
|  |  obj-$(CONFIG_CAIF)		+= caif/ | ||||||
|  |  ifneq ($(CONFIG_DCB),) | ||||||
|  | --- a/net/rfkill/Kconfig | ||||||
|  | +++ b/net/rfkill/Kconfig | ||||||
|  | @@ -1,7 +1,11 @@ | ||||||
|  |  # | ||||||
|  |  # RF switch subsystem configuration | ||||||
|  |  # | ||||||
|  | -menuconfig RFKILL | ||||||
|  | +config RFKILL | ||||||
|  | +	bool | ||||||
|  | +	default y | ||||||
|  | + | ||||||
|  | +menuconfig RFKILL_FULL | ||||||
|  |  	tristate "RF switch subsystem support" | ||||||
|  |  	help | ||||||
|  |  	  Say Y here if you want to have control over RF switches | ||||||
|  | @@ -13,19 +17,19 @@ menuconfig RFKILL | ||||||
|  |  # LED trigger support | ||||||
|  |  config RFKILL_LEDS | ||||||
|  |  	bool | ||||||
|  | -	depends on RFKILL | ||||||
|  | +	depends on RFKILL_FULL | ||||||
|  |  	depends on LEDS_TRIGGERS = y || RFKILL = LEDS_TRIGGERS | ||||||
|  |  	default y | ||||||
|  |   | ||||||
|  |  config RFKILL_INPUT | ||||||
|  |  	bool "RF switch input support" if EXPERT | ||||||
|  | -	depends on RFKILL | ||||||
|  | +	depends on RFKILL_FULL | ||||||
|  |  	depends on INPUT = y || RFKILL = INPUT | ||||||
|  |  	default y if !EXPERT | ||||||
|  |   | ||||||
|  |  config RFKILL_GPIO | ||||||
|  |  	tristate "GPIO RFKILL driver" | ||||||
|  | -	depends on RFKILL | ||||||
|  | +	depends on RFKILL_FULL | ||||||
|  |  	depends on GPIOLIB || COMPILE_TEST | ||||||
|  |  	default n | ||||||
|  |  	help | ||||||
|  | --- a/net/rfkill/Makefile | ||||||
|  | +++ b/net/rfkill/Makefile | ||||||
|  | @@ -4,5 +4,5 @@ | ||||||
|  |   | ||||||
|  |  rfkill-y			+= core.o | ||||||
|  |  rfkill-$(CONFIG_RFKILL_INPUT)	+= input.o | ||||||
|  | -obj-$(CONFIG_RFKILL)		+= rfkill.o | ||||||
|  | +obj-$(CONFIG_RFKILL_FULL)	+= rfkill.o | ||||||
|  |  obj-$(CONFIG_RFKILL_GPIO)	+= rfkill-gpio.o | ||||||
| @@ -0,0 +1,38 @@ | |||||||
|  | From: John Crispin <john@phrozen.org> | ||||||
|  | Subject: hack: kernel: add generic image_cmdline hack to MIPS targets | ||||||
|  |  | ||||||
|  | lede-commit: d59f5b3a987a48508257a0ddbaeadc7909f9f976 | ||||||
|  | Signed-off-by: Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | --- | ||||||
|  |  arch/mips/Kconfig       | 4 ++++ | ||||||
|  |  arch/mips/kernel/head.S | 6 ++++++ | ||||||
|  |  2 files changed, 10 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/arch/mips/Kconfig | ||||||
|  | +++ b/arch/mips/Kconfig | ||||||
|  | @@ -1157,6 +1157,10 @@ config SYNC_R4K | ||||||
|  |  config MIPS_MACHINE | ||||||
|  |  	def_bool n | ||||||
|  |   | ||||||
|  | +config IMAGE_CMDLINE_HACK | ||||||
|  | +	bool "OpenWrt specific image command line hack" | ||||||
|  | +	default n | ||||||
|  | + | ||||||
|  |  config NO_IOPORT_MAP | ||||||
|  |  	def_bool n | ||||||
|  |   | ||||||
|  | --- a/arch/mips/kernel/head.S | ||||||
|  | +++ b/arch/mips/kernel/head.S | ||||||
|  | @@ -79,6 +79,12 @@ FEXPORT(__kernel_entry) | ||||||
|  |  	j	kernel_entry | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  | +#ifdef CONFIG_IMAGE_CMDLINE_HACK | ||||||
|  | +	.ascii	"CMDLINE:" | ||||||
|  | +EXPORT(__image_cmdline) | ||||||
|  | +	.fill	0x400 | ||||||
|  | +#endif /* CONFIG_IMAGE_CMDLINE_HACK */ | ||||||
|  | + | ||||||
|  |  	__REF | ||||||
|  |   | ||||||
|  |  NESTED(kernel_entry, 16, sp)			# kernel entry point | ||||||
| @@ -0,0 +1,38 @@ | |||||||
|  | From 107c0964cb8db7ca28ac5199426414fdab3c274d Mon Sep 17 00:00:00 2001 | ||||||
|  | From: "Alexandros C. Couloumbis" <alex@ozo.com> | ||||||
|  | Date: Fri, 7 Jul 2017 17:14:51 +0200 | ||||||
|  | Subject: hack: arch: powerpc: drop register save/restore library from modules | ||||||
|  |  | ||||||
|  | Upstream GCC uses a libgcc function for saving/restoring registers. This | ||||||
|  | makes the code bigger, and upstream kernels need to carry that function | ||||||
|  | for every single kernel module. Our GCC is patched to avoid those | ||||||
|  | references, so we can drop the extra bloat for modules. | ||||||
|  |  | ||||||
|  | lede-commit: e8e1084654f50904e6bf77b70b2de3f137d7b3ec | ||||||
|  | Signed-off-by: Alexandros C. Couloumbis <alex@ozo.com> | ||||||
|  | --- | ||||||
|  |  arch/powerpc/Makefile | 1 - | ||||||
|  |  1 file changed, 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/arch/powerpc/Makefile | ||||||
|  | +++ b/arch/powerpc/Makefile | ||||||
|  | @@ -59,19 +59,6 @@ machine-$(CONFIG_PPC64) += 64 | ||||||
|  |  machine-$(CONFIG_CPU_LITTLE_ENDIAN) += le | ||||||
|  |  UTS_MACHINE := $(subst $(space),,$(machine-y)) | ||||||
|  |   | ||||||
|  | -# XXX This needs to be before we override LD below | ||||||
|  | -ifdef CONFIG_PPC32 | ||||||
|  | -KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o | ||||||
|  | -else | ||||||
|  | -ifeq ($(call ld-ifversion, -ge, 225000000, y),y) | ||||||
|  | -# Have the linker provide sfpr if possible. | ||||||
|  | -# There is a corresponding test in arch/powerpc/lib/Makefile | ||||||
|  | -KBUILD_LDFLAGS_MODULE += --save-restore-funcs | ||||||
|  | -else | ||||||
|  | -KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o | ||||||
|  | -endif | ||||||
|  | -endif | ||||||
|  | - | ||||||
|  |  ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y) | ||||||
|  |  override LD	+= -EL | ||||||
|  |  LDEMULATION	:= lppc | ||||||
							
								
								
									
										1040
									
								
								target/linux/generic/hack-4.14/531-debloat_lzma.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1040
									
								
								target/linux/generic/hack-4.14/531-debloat_lzma.patch
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | From c6905cfdeb31a5c049db3da434b10fa0d3e83569 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Fri, 7 Jul 2017 17:18:54 +0200 | ||||||
|  | Subject: bridge: only accept EAP locally | ||||||
|  |  | ||||||
|  | When bridging, do not forward EAP frames to other ports, only deliver | ||||||
|  | them locally, regardless of the state. | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  net/bridge/br_input.c | 7 +++++-- | ||||||
|  |  1 file changed, 5 insertions(+), 2 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/net/bridge/br_input.c | ||||||
|  | +++ b/net/bridge/br_input.c | ||||||
|  | @@ -166,11 +166,14 @@ int br_handle_frame_finish(struct net *n | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	BR_INPUT_SKB_CB(skb)->brdev = br->dev; | ||||||
|  | + | ||||||
|  | +	if (skb->protocol == htons(ETH_P_PAE)) | ||||||
|  | +		return br_pass_frame_up(skb); | ||||||
|  | + | ||||||
|  |  	if (p->state == BR_STATE_LEARNING) | ||||||
|  |  		goto drop; | ||||||
|  |   | ||||||
|  | -	BR_INPUT_SKB_CB(skb)->brdev = br->dev; | ||||||
|  | - | ||||||
|  |  	if (IS_ENABLED(CONFIG_INET) && skb->protocol == htons(ETH_P_ARP)) | ||||||
|  |  		br_do_proxy_arp(skb, br, vid, p); | ||||||
|  |   | ||||||
							
								
								
									
										76
									
								
								target/linux/generic/hack-4.14/641-bridge_port_isolate.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								target/linux/generic/hack-4.14/641-bridge_port_isolate.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | |||||||
|  | From e988390850731aa1697ed09d47b0932fac1af175 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Fri, 7 Jul 2017 17:20:03 +0200 | ||||||
|  | Subject: bridge: port isolate | ||||||
|  |  | ||||||
|  | Isolating individual bridge ports | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  include/linux/if_bridge.h | 1 + | ||||||
|  |  net/bridge/br_forward.c   | 5 +++++ | ||||||
|  |  net/bridge/br_input.c     | 3 +++ | ||||||
|  |  net/bridge/br_sysfs_if.c  | 2 ++ | ||||||
|  |  4 files changed, 11 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/include/linux/if_bridge.h | ||||||
|  | +++ b/include/linux/if_bridge.h | ||||||
|  | @@ -49,6 +49,7 @@ struct br_ip_list { | ||||||
|  |  #define BR_MULTICAST_TO_UNICAST	BIT(12) | ||||||
|  |  #define BR_VLAN_TUNNEL		BIT(13) | ||||||
|  |  #define BR_BCAST_FLOOD		BIT(14) | ||||||
|  | +#define BR_ISOLATE_MODE		BIT(15) | ||||||
|  |   | ||||||
|  |  #define BR_DEFAULT_AGEING_TIME	(300 * HZ) | ||||||
|  |   | ||||||
|  | --- a/net/bridge/br_forward.c | ||||||
|  | +++ b/net/bridge/br_forward.c | ||||||
|  | @@ -141,6 +141,9 @@ static int deliver_clone(const struct ne | ||||||
|  |  void br_forward(const struct net_bridge_port *to, | ||||||
|  |  		struct sk_buff *skb, bool local_rcv, bool local_orig) | ||||||
|  |  { | ||||||
|  | +	if (to->flags & BR_ISOLATE_MODE) | ||||||
|  | +		to = NULL; | ||||||
|  | + | ||||||
|  |  	if (to && should_deliver(to, skb)) { | ||||||
|  |  		if (local_rcv) | ||||||
|  |  			deliver_clone(to, skb, local_orig); | ||||||
|  | @@ -183,6 +186,8 @@ void br_flood(struct net_bridge *br, str | ||||||
|  |  	struct net_bridge_port *p; | ||||||
|  |   | ||||||
|  |  	list_for_each_entry_rcu(p, &br->port_list, list) { | ||||||
|  | +		if (!local_orig && (p->flags & BR_ISOLATE_MODE)) | ||||||
|  | +			continue; | ||||||
|  |  		/* Do not flood unicast traffic to ports that turn it off, nor | ||||||
|  |  		 * other traffic if flood off, except for traffic we originate | ||||||
|  |  		 */ | ||||||
|  | --- a/net/bridge/br_input.c | ||||||
|  | +++ b/net/bridge/br_input.c | ||||||
|  | @@ -177,6 +177,9 @@ int br_handle_frame_finish(struct net *n | ||||||
|  |  	if (IS_ENABLED(CONFIG_INET) && skb->protocol == htons(ETH_P_ARP)) | ||||||
|  |  		br_do_proxy_arp(skb, br, vid, p); | ||||||
|  |   | ||||||
|  | +	if (p->flags & BR_ISOLATE_MODE) | ||||||
|  | +		return br_pass_frame_up(skb); | ||||||
|  | + | ||||||
|  |  	switch (pkt_type) { | ||||||
|  |  	case BR_PKT_MULTICAST: | ||||||
|  |  		mdst = br_mdb_get(br, skb, vid); | ||||||
|  | --- a/net/bridge/br_sysfs_if.c | ||||||
|  | +++ b/net/bridge/br_sysfs_if.c | ||||||
|  | @@ -174,6 +174,7 @@ BRPORT_ATTR_FLAG(proxyarp, BR_PROXYARP); | ||||||
|  |  BRPORT_ATTR_FLAG(proxyarp_wifi, BR_PROXYARP_WIFI); | ||||||
|  |  BRPORT_ATTR_FLAG(multicast_flood, BR_MCAST_FLOOD); | ||||||
|  |  BRPORT_ATTR_FLAG(broadcast_flood, BR_BCAST_FLOOD); | ||||||
|  | +BRPORT_ATTR_FLAG(isolate_mode, BR_ISOLATE_MODE); | ||||||
|  |   | ||||||
|  |  #ifdef CONFIG_BRIDGE_IGMP_SNOOPING | ||||||
|  |  static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) | ||||||
|  | @@ -223,6 +224,7 @@ static const struct brport_attribute *br | ||||||
|  |  	&brport_attr_proxyarp_wifi, | ||||||
|  |  	&brport_attr_multicast_flood, | ||||||
|  |  	&brport_attr_broadcast_flood, | ||||||
|  | +	&brport_attr_isolate_mode, | ||||||
|  |  	NULL | ||||||
|  |  }; | ||||||
|  |   | ||||||
| @@ -0,0 +1,24 @@ | |||||||
|  | From 6d3bc769657b0ee7c7506dad9911111c4226a7ea Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Imre Kaloz <kaloz@openwrt.org> | ||||||
|  | Date: Fri, 7 Jul 2017 17:21:05 +0200 | ||||||
|  | Subject: mac80211: increase wireless mesh header size | ||||||
|  |  | ||||||
|  | lede-commit 3d4466cfd8f75f717efdb1f96fdde3c70d865fc1 | ||||||
|  | Signed-off-by: Imre Kaloz <kaloz@openwrt.org> | ||||||
|  | --- | ||||||
|  |  include/linux/netdevice.h | 4 ++-- | ||||||
|  |  1 file changed, 2 insertions(+), 2 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/include/linux/netdevice.h | ||||||
|  | +++ b/include/linux/netdevice.h | ||||||
|  | @@ -138,8 +138,8 @@ static inline bool dev_xmit_complete(int | ||||||
|  |   | ||||||
|  |  #if defined(CONFIG_HYPERV_NET) | ||||||
|  |  # define LL_MAX_HEADER 128 | ||||||
|  | -#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) | ||||||
|  | -# if defined(CONFIG_MAC80211_MESH) | ||||||
|  | +#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) || 1 | ||||||
|  | +# if defined(CONFIG_MAC80211_MESH) || 1 | ||||||
|  |  #  define LL_MAX_HEADER 128 | ||||||
|  |  # else | ||||||
|  |  #  define LL_MAX_HEADER 96 | ||||||
							
								
								
									
										27
									
								
								target/linux/generic/hack-4.14/660-fq_codel_defaults.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								target/linux/generic/hack-4.14/660-fq_codel_defaults.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | From a6ccb238939b25851474a279b20367fd24a0e816 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Fri, 7 Jul 2017 17:21:53 +0200 | ||||||
|  | Subject:  hack: net: fq_codel: tune defaults for small devices | ||||||
|  |  | ||||||
|  | Assume that x86_64 devices always have a big memory and do not need this  | ||||||
|  | optimization compared to devices with only 32 MB or 64 MB RAM. | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  net/sched/sch_fq_codel.c | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/net/sched/sch_fq_codel.c | ||||||
|  | +++ b/net/sched/sch_fq_codel.c | ||||||
|  | @@ -465,7 +465,11 @@ static int fq_codel_init(struct Qdisc *s | ||||||
|  |   | ||||||
|  |  	sch->limit = 10*1024; | ||||||
|  |  	q->flows_cnt = 1024; | ||||||
|  | +#ifdef CONFIG_X86_64 | ||||||
|  |  	q->memory_limit = 32 << 20; /* 32 MBytes */ | ||||||
|  | +#else | ||||||
|  | +	q->memory_limit = 4 << 20; /* 4 MBytes */ | ||||||
|  | +#endif | ||||||
|  |  	q->drop_batch_size = 64; | ||||||
|  |  	q->quantum = psched_mtu(qdisc_dev(sch)); | ||||||
|  |  	INIT_LIST_HEAD(&q->new_flows); | ||||||
| @@ -0,0 +1,94 @@ | |||||||
|  | From 1d418f7e88035ed7a94073f6354246c66e9193e9 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Fri, 7 Jul 2017 17:22:58 +0200 | ||||||
|  | Subject: fq_codel: switch default qdisc from pfifo_fast to fq_codel and remove pfifo_fast | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  include/net/sch_generic.h | 3 ++- | ||||||
|  |  net/sched/Kconfig         | 3 ++- | ||||||
|  |  net/sched/sch_api.c       | 2 +- | ||||||
|  |  net/sched/sch_fq_codel.c  | 3 ++- | ||||||
|  |  net/sched/sch_generic.c   | 4 ++-- | ||||||
|  |  5 files changed, 9 insertions(+), 6 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/include/net/sch_generic.h | ||||||
|  | +++ b/include/net/sch_generic.h | ||||||
|  | @@ -369,12 +369,13 @@ extern struct Qdisc_ops noop_qdisc_ops; | ||||||
|  |  extern struct Qdisc_ops pfifo_fast_ops; | ||||||
|  |  extern struct Qdisc_ops mq_qdisc_ops; | ||||||
|  |  extern struct Qdisc_ops noqueue_qdisc_ops; | ||||||
|  | +extern struct Qdisc_ops fq_codel_qdisc_ops; | ||||||
|  |  extern const struct Qdisc_ops *default_qdisc_ops; | ||||||
|  |  static inline const struct Qdisc_ops * | ||||||
|  |  get_default_qdisc_ops(const struct net_device *dev, int ntx) | ||||||
|  |  { | ||||||
|  |  	return ntx < dev->real_num_tx_queues ? | ||||||
|  | -			default_qdisc_ops : &pfifo_fast_ops; | ||||||
|  | +			default_qdisc_ops : &fq_codel_qdisc_ops; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  struct Qdisc_class_common { | ||||||
|  | --- a/net/sched/Kconfig | ||||||
|  | +++ b/net/sched/Kconfig | ||||||
|  | @@ -3,8 +3,9 @@ | ||||||
|  |  #  | ||||||
|  |   | ||||||
|  |  menuconfig NET_SCHED | ||||||
|  | -	bool "QoS and/or fair queueing" | ||||||
|  | +	def_bool y | ||||||
|  |  	select NET_SCH_FIFO | ||||||
|  | +	select NET_SCH_FQ_CODEL | ||||||
|  |  	---help--- | ||||||
|  |  	  When the kernel has several packets to send out over a network | ||||||
|  |  	  device, it has to decide which ones to send first, which ones to | ||||||
|  | --- a/net/sched/sch_api.c | ||||||
|  | +++ b/net/sched/sch_api.c | ||||||
|  | @@ -2014,7 +2014,7 @@ static int __init pktsched_init(void) | ||||||
|  |  		return err; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	register_qdisc(&pfifo_fast_ops); | ||||||
|  | +	register_qdisc(&fq_codel_qdisc_ops); | ||||||
|  |  	register_qdisc(&pfifo_qdisc_ops); | ||||||
|  |  	register_qdisc(&bfifo_qdisc_ops); | ||||||
|  |  	register_qdisc(&pfifo_head_drop_qdisc_ops); | ||||||
|  | --- a/net/sched/sch_fq_codel.c | ||||||
|  | +++ b/net/sched/sch_fq_codel.c | ||||||
|  | @@ -694,7 +694,7 @@ static const struct Qdisc_class_ops fq_c | ||||||
|  |  	.walk		=	fq_codel_walk, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | -static struct Qdisc_ops fq_codel_qdisc_ops __read_mostly = { | ||||||
|  | +struct Qdisc_ops fq_codel_qdisc_ops __read_mostly = { | ||||||
|  |  	.cl_ops		=	&fq_codel_class_ops, | ||||||
|  |  	.id		=	"fq_codel", | ||||||
|  |  	.priv_size	=	sizeof(struct fq_codel_sched_data), | ||||||
|  | @@ -709,6 +709,7 @@ static struct Qdisc_ops fq_codel_qdisc_o | ||||||
|  |  	.dump_stats =	fq_codel_dump_stats, | ||||||
|  |  	.owner		=	THIS_MODULE, | ||||||
|  |  }; | ||||||
|  | +EXPORT_SYMBOL(fq_codel_qdisc_ops); | ||||||
|  |   | ||||||
|  |  static int __init fq_codel_module_init(void) | ||||||
|  |  { | ||||||
|  | --- a/net/sched/sch_generic.c | ||||||
|  | +++ b/net/sched/sch_generic.c | ||||||
|  | @@ -32,7 +32,7 @@ | ||||||
|  |  #include <trace/events/qdisc.h> | ||||||
|  |   | ||||||
|  |  /* Qdisc to use by default */ | ||||||
|  | -const struct Qdisc_ops *default_qdisc_ops = &pfifo_fast_ops; | ||||||
|  | +const struct Qdisc_ops *default_qdisc_ops = &fq_codel_qdisc_ops; | ||||||
|  |  EXPORT_SYMBOL(default_qdisc_ops); | ||||||
|  |   | ||||||
|  |  /* Main transmission queue. */ | ||||||
|  | @@ -764,7 +764,7 @@ static void attach_one_default_qdisc(str | ||||||
|  |  				     void *_unused) | ||||||
|  |  { | ||||||
|  |  	struct Qdisc *qdisc; | ||||||
|  | -	const struct Qdisc_ops *ops = default_qdisc_ops; | ||||||
|  | +	const struct Qdisc_ops *ops = &fq_codel_qdisc_ops; | ||||||
|  |   | ||||||
|  |  	if (dev->priv_flags & IFF_NO_QUEUE) | ||||||
|  |  		ops = &noqueue_qdisc_ops; | ||||||
							
								
								
									
										159
									
								
								target/linux/generic/hack-4.14/662-remove_pfifo_fast.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								target/linux/generic/hack-4.14/662-remove_pfifo_fast.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,159 @@ | |||||||
|  | From b531d492d5ef1cf9dba0f4888eb5fd8624a6d762 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Fri, 7 Jul 2017 17:23:42 +0200 | ||||||
|  | Subject: net: sched: switch default qdisc from pfifo_fast to fq_codel and remove pfifo_fast | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  net/sched/sch_generic.c | 140 ------------------------------------------------ | ||||||
|  |  1 file changed, 140 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/net/sched/sch_generic.c | ||||||
|  | +++ b/net/sched/sch_generic.c | ||||||
|  | @@ -453,146 +453,6 @@ struct Qdisc_ops noqueue_qdisc_ops __rea | ||||||
|  |  	.owner		=	THIS_MODULE, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | -static const u8 prio2band[TC_PRIO_MAX + 1] = { | ||||||
|  | -	1, 2, 2, 2, 1, 2, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1 | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -/* 3-band FIFO queue: old style, but should be a bit faster than | ||||||
|  | -   generic prio+fifo combination. | ||||||
|  | - */ | ||||||
|  | - | ||||||
|  | -#define PFIFO_FAST_BANDS 3 | ||||||
|  | - | ||||||
|  | -/* | ||||||
|  | - * Private data for a pfifo_fast scheduler containing: | ||||||
|  | - * 	- queues for the three band | ||||||
|  | - * 	- bitmap indicating which of the bands contain skbs | ||||||
|  | - */ | ||||||
|  | -struct pfifo_fast_priv { | ||||||
|  | -	u32 bitmap; | ||||||
|  | -	struct qdisc_skb_head q[PFIFO_FAST_BANDS]; | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  | -/* | ||||||
|  | - * Convert a bitmap to the first band number where an skb is queued, where: | ||||||
|  | - * 	bitmap=0 means there are no skbs on any band. | ||||||
|  | - * 	bitmap=1 means there is an skb on band 0. | ||||||
|  | - *	bitmap=7 means there are skbs on all 3 bands, etc. | ||||||
|  | - */ | ||||||
|  | -static const int bitmap2band[] = {-1, 0, 1, 0, 2, 0, 1, 0}; | ||||||
|  | - | ||||||
|  | -static inline struct qdisc_skb_head *band2list(struct pfifo_fast_priv *priv, | ||||||
|  | -					     int band) | ||||||
|  | -{ | ||||||
|  | -	return priv->q + band; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc *qdisc, | ||||||
|  | -			      struct sk_buff **to_free) | ||||||
|  | -{ | ||||||
|  | -	if (qdisc->q.qlen < qdisc_dev(qdisc)->tx_queue_len) { | ||||||
|  | -		int band = prio2band[skb->priority & TC_PRIO_MAX]; | ||||||
|  | -		struct pfifo_fast_priv *priv = qdisc_priv(qdisc); | ||||||
|  | -		struct qdisc_skb_head *list = band2list(priv, band); | ||||||
|  | - | ||||||
|  | -		priv->bitmap |= (1 << band); | ||||||
|  | -		qdisc->q.qlen++; | ||||||
|  | -		return __qdisc_enqueue_tail(skb, qdisc, list); | ||||||
|  | -	} | ||||||
|  | - | ||||||
|  | -	return qdisc_drop(skb, qdisc, to_free); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static struct sk_buff *pfifo_fast_dequeue(struct Qdisc *qdisc) | ||||||
|  | -{ | ||||||
|  | -	struct pfifo_fast_priv *priv = qdisc_priv(qdisc); | ||||||
|  | -	int band = bitmap2band[priv->bitmap]; | ||||||
|  | - | ||||||
|  | -	if (likely(band >= 0)) { | ||||||
|  | -		struct qdisc_skb_head *qh = band2list(priv, band); | ||||||
|  | -		struct sk_buff *skb = __qdisc_dequeue_head(qh); | ||||||
|  | - | ||||||
|  | -		if (likely(skb != NULL)) { | ||||||
|  | -			qdisc_qstats_backlog_dec(qdisc, skb); | ||||||
|  | -			qdisc_bstats_update(qdisc, skb); | ||||||
|  | -		} | ||||||
|  | - | ||||||
|  | -		qdisc->q.qlen--; | ||||||
|  | -		if (qh->qlen == 0) | ||||||
|  | -			priv->bitmap &= ~(1 << band); | ||||||
|  | - | ||||||
|  | -		return skb; | ||||||
|  | -	} | ||||||
|  | - | ||||||
|  | -	return NULL; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static struct sk_buff *pfifo_fast_peek(struct Qdisc *qdisc) | ||||||
|  | -{ | ||||||
|  | -	struct pfifo_fast_priv *priv = qdisc_priv(qdisc); | ||||||
|  | -	int band = bitmap2band[priv->bitmap]; | ||||||
|  | - | ||||||
|  | -	if (band >= 0) { | ||||||
|  | -		struct qdisc_skb_head *qh = band2list(priv, band); | ||||||
|  | - | ||||||
|  | -		return qh->head; | ||||||
|  | -	} | ||||||
|  | - | ||||||
|  | -	return NULL; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static void pfifo_fast_reset(struct Qdisc *qdisc) | ||||||
|  | -{ | ||||||
|  | -	int prio; | ||||||
|  | -	struct pfifo_fast_priv *priv = qdisc_priv(qdisc); | ||||||
|  | - | ||||||
|  | -	for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) | ||||||
|  | -		__qdisc_reset_queue(band2list(priv, prio)); | ||||||
|  | - | ||||||
|  | -	priv->bitmap = 0; | ||||||
|  | -	qdisc->qstats.backlog = 0; | ||||||
|  | -	qdisc->q.qlen = 0; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static int pfifo_fast_dump(struct Qdisc *qdisc, struct sk_buff *skb) | ||||||
|  | -{ | ||||||
|  | -	struct tc_prio_qopt opt = { .bands = PFIFO_FAST_BANDS }; | ||||||
|  | - | ||||||
|  | -	memcpy(&opt.priomap, prio2band, TC_PRIO_MAX + 1); | ||||||
|  | -	if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt)) | ||||||
|  | -		goto nla_put_failure; | ||||||
|  | -	return skb->len; | ||||||
|  | - | ||||||
|  | -nla_put_failure: | ||||||
|  | -	return -1; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt) | ||||||
|  | -{ | ||||||
|  | -	int prio; | ||||||
|  | -	struct pfifo_fast_priv *priv = qdisc_priv(qdisc); | ||||||
|  | - | ||||||
|  | -	for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) | ||||||
|  | -		qdisc_skb_head_init(band2list(priv, prio)); | ||||||
|  | - | ||||||
|  | -	/* Can by-pass the queue discipline */ | ||||||
|  | -	qdisc->flags |= TCQ_F_CAN_BYPASS; | ||||||
|  | -	return 0; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -struct Qdisc_ops pfifo_fast_ops __read_mostly = { | ||||||
|  | -	.id		=	"pfifo_fast", | ||||||
|  | -	.priv_size	=	sizeof(struct pfifo_fast_priv), | ||||||
|  | -	.enqueue	=	pfifo_fast_enqueue, | ||||||
|  | -	.dequeue	=	pfifo_fast_dequeue, | ||||||
|  | -	.peek		=	pfifo_fast_peek, | ||||||
|  | -	.init		=	pfifo_fast_init, | ||||||
|  | -	.reset		=	pfifo_fast_reset, | ||||||
|  | -	.dump		=	pfifo_fast_dump, | ||||||
|  | -	.owner		=	THIS_MODULE, | ||||||
|  | -}; | ||||||
|  | -EXPORT_SYMBOL(pfifo_fast_ops); | ||||||
|  | - | ||||||
|  |  static struct lock_class_key qdisc_tx_busylock; | ||||||
|  |  static struct lock_class_key qdisc_running_key; | ||||||
|  |   | ||||||
							
								
								
									
										128
									
								
								target/linux/generic/hack-4.14/700-swconfig_switch_drivers.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								target/linux/generic/hack-4.14/700-swconfig_switch_drivers.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | |||||||
|  | From 36e516290611e613aa92996cb4339561452695b4 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Fri, 7 Jul 2017 17:24:23 +0200 | ||||||
|  | Subject: net: swconfig: adds openwrt switch layer | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  drivers/net/phy/Kconfig   | 83 +++++++++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  drivers/net/phy/Makefile  | 15 +++++++++ | ||||||
|  |  include/uapi/linux/Kbuild |  1 + | ||||||
|  |  3 files changed, 99 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/phy/Kconfig | ||||||
|  | +++ b/drivers/net/phy/Kconfig | ||||||
|  | @@ -198,6 +198,89 @@ config LED_TRIGGER_PHY | ||||||
|  |  		<Speed in megabits>Mbps or <Speed in gigabits>Gbps | ||||||
|  |   | ||||||
|  |   | ||||||
|  | +comment "Switch configuration API + drivers" | ||||||
|  | + | ||||||
|  | +config SWCONFIG | ||||||
|  | +	tristate "Switch configuration API" | ||||||
|  | +	---help--- | ||||||
|  | +	  Switch configuration API using netlink. This allows | ||||||
|  | +	  you to configure the VLAN features of certain switches. | ||||||
|  | + | ||||||
|  | +config SWCONFIG_LEDS | ||||||
|  | +	bool "Switch LED trigger support" | ||||||
|  | +	depends on (SWCONFIG && LEDS_TRIGGERS) | ||||||
|  | + | ||||||
|  | +config ADM6996_PHY | ||||||
|  | +	tristate "Driver for ADM6996 switches" | ||||||
|  | +	select SWCONFIG | ||||||
|  | +	---help--- | ||||||
|  | +	  Currently supports the ADM6996FC and ADM6996M switches. | ||||||
|  | +	  Support for FC is very limited. | ||||||
|  | + | ||||||
|  | +config AR8216_PHY | ||||||
|  | +	tristate "Driver for Atheros AR8216 switches" | ||||||
|  | +	select ETHERNET_PACKET_MANGLE | ||||||
|  | +	select SWCONFIG | ||||||
|  | + | ||||||
|  | +config AR8216_PHY_LEDS | ||||||
|  | +	bool "Atheros AR8216 switch LED support" | ||||||
|  | +	depends on (AR8216_PHY && LEDS_CLASS) | ||||||
|  | + | ||||||
|  | +source "drivers/net/phy/b53/Kconfig" | ||||||
|  | + | ||||||
|  | +config IP17XX_PHY | ||||||
|  | +	tristate "Driver for IC+ IP17xx switches" | ||||||
|  | +	select SWCONFIG | ||||||
|  | + | ||||||
|  | +config MVSWITCH_PHY | ||||||
|  | +	tristate "Driver for Marvell 88E6060 switches" | ||||||
|  | +	select ETHERNET_PACKET_MANGLE | ||||||
|  | + | ||||||
|  | +config MVSW61XX_PHY | ||||||
|  | +	tristate "Driver for Marvell 88E6171/6172 switches" | ||||||
|  | +	select SWCONFIG | ||||||
|  | + | ||||||
|  | +config PSB6970_PHY | ||||||
|  | +	tristate "Lantiq XWAY Tantos (PSB6970) Ethernet switch" | ||||||
|  | +	select SWCONFIG | ||||||
|  | +	select ETHERNET_PACKET_MANGLE | ||||||
|  | + | ||||||
|  | +config RTL8306_PHY | ||||||
|  | +	tristate "Driver for Realtek RTL8306S switches" | ||||||
|  | +	select SWCONFIG | ||||||
|  | + | ||||||
|  | +config RTL8366_SMI | ||||||
|  | +	tristate "Driver for the RTL8366 SMI interface" | ||||||
|  | +	depends on GPIOLIB | ||||||
|  | +	---help--- | ||||||
|  | +	  This module implements the SMI interface protocol which is used | ||||||
|  | +	  by some RTL8366 ethernet switch devices via the generic GPIO API. | ||||||
|  | + | ||||||
|  | +if RTL8366_SMI | ||||||
|  | + | ||||||
|  | +config RTL8366_SMI_DEBUG_FS | ||||||
|  | +	bool "RTL8366 SMI interface debugfs support" | ||||||
|  | +        depends on DEBUG_FS | ||||||
|  | +        default n | ||||||
|  | + | ||||||
|  | +config RTL8366S_PHY | ||||||
|  | +	tristate "Driver for the Realtek RTL8366S switch" | ||||||
|  | +	select SWCONFIG | ||||||
|  | + | ||||||
|  | +config RTL8366RB_PHY | ||||||
|  | +	tristate "Driver for the Realtek RTL8366RB switch" | ||||||
|  | +	select SWCONFIG | ||||||
|  | + | ||||||
|  | +config RTL8367_PHY | ||||||
|  | +	tristate "Driver for the Realtek RTL8367R/M switches" | ||||||
|  | +	select SWCONFIG | ||||||
|  | + | ||||||
|  | +config RTL8367B_PHY | ||||||
|  | +	tristate "Driver fot the Realtek RTL8367R-VB switch" | ||||||
|  | +	select SWCONFIG | ||||||
|  | + | ||||||
|  | +endif # RTL8366_SMI | ||||||
|  | + | ||||||
|  |  comment "MII PHY device drivers" | ||||||
|  |   | ||||||
|  |  config SFP | ||||||
|  | --- a/drivers/net/phy/Makefile | ||||||
|  | +++ b/drivers/net/phy/Makefile | ||||||
|  | @@ -22,6 +22,21 @@ libphy-$(CONFIG_LED_TRIGGER_PHY)	+= phy_ | ||||||
|  |  obj-$(CONFIG_PHYLINK)		+= phylink.o | ||||||
|  |  obj-$(CONFIG_PHYLIB)		+= libphy.o | ||||||
|  |   | ||||||
|  | +obj-$(CONFIG_SWCONFIG)		+= swconfig.o | ||||||
|  | +obj-$(CONFIG_ADM6996_PHY)	+= adm6996.o | ||||||
|  | +obj-$(CONFIG_AR8216_PHY)	+= ar8216.o ar8327.o | ||||||
|  | +obj-$(CONFIG_SWCONFIG_B53)	+= b53/ | ||||||
|  | +obj-$(CONFIG_IP17XX_PHY)	+= ip17xx.o | ||||||
|  | +obj-$(CONFIG_MVSWITCH_PHY)	+= mvswitch.o | ||||||
|  | +obj-$(CONFIG_MVSW61XX_PHY)	+= mvsw61xx.o | ||||||
|  | +obj-$(CONFIG_PSB6970_PHY)	+= psb6970.o | ||||||
|  | +obj-$(CONFIG_RTL8306_PHY)	+= rtl8306.o | ||||||
|  | +obj-$(CONFIG_RTL8366_SMI)	+= rtl8366_smi.o | ||||||
|  | +obj-$(CONFIG_RTL8366S_PHY)	+= rtl8366s.o | ||||||
|  | +obj-$(CONFIG_RTL8366RB_PHY)	+= rtl8366rb.o | ||||||
|  | +obj-$(CONFIG_RTL8367_PHY)	+= rtl8367.o | ||||||
|  | +obj-$(CONFIG_RTL8367B_PHY)	+= rtl8367b.o | ||||||
|  | + | ||||||
|  |  obj-$(CONFIG_MDIO_BCM_IPROC)	+= mdio-bcm-iproc.o | ||||||
|  |  obj-$(CONFIG_MDIO_BCM_UNIMAC)	+= mdio-bcm-unimac.o | ||||||
|  |  obj-$(CONFIG_MDIO_BITBANG)	+= mdio-bitbang.o | ||||||
| @@ -0,0 +1,27 @@ | |||||||
|  | --- a/include/linux/phy.h | ||||||
|  | +++ b/include/linux/phy.h | ||||||
|  | @@ -547,6 +547,12 @@ struct phy_driver { | ||||||
|  |  	/* Determines the negotiated speed and duplex */ | ||||||
|  |  	int (*read_status)(struct phy_device *phydev); | ||||||
|  |   | ||||||
|  | +	/*  | ||||||
|  | +	 * Update the value in phydev->link to reflect the  | ||||||
|  | +	 * current link value | ||||||
|  | +	 */ | ||||||
|  | +	int (*update_link)(struct phy_device *phydev); | ||||||
|  | + | ||||||
|  |  	/* Clears any pending interrupts */ | ||||||
|  |  	int (*ack_interrupt)(struct phy_device *phydev); | ||||||
|  |   | ||||||
|  | --- a/drivers/net/phy/phy_device.c | ||||||
|  | +++ b/drivers/net/phy/phy_device.c | ||||||
|  | @@ -1437,6 +1437,9 @@ int genphy_update_link(struct phy_device | ||||||
|  |  { | ||||||
|  |  	int status; | ||||||
|  |   | ||||||
|  | +	if (phydev->drv && phydev->drv->update_link) | ||||||
|  | +		return phydev->drv->update_link(phydev); | ||||||
|  | + | ||||||
|  |  	/* Do a fake read */ | ||||||
|  |  	status = phy_read(phydev, MII_BMSR); | ||||||
|  |  	if (status < 0) | ||||||
							
								
								
									
										176
									
								
								target/linux/generic/hack-4.14/721-phy_packets.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								target/linux/generic/hack-4.14/721-phy_packets.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,176 @@ | |||||||
|  | From ffe387740bbe88dd88bbe04d6375902708003d6e Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Fri, 7 Jul 2017 17:25:00 +0200 | ||||||
|  | Subject: net: add packet mangeling patch | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  include/linux/netdevice.h | 11 +++++++++++ | ||||||
|  |  include/linux/skbuff.h    | 14 ++++---------- | ||||||
|  |  net/Kconfig               |  6 ++++++ | ||||||
|  |  net/core/dev.c            | 18 ++++++++++++++---- | ||||||
|  |  net/core/skbuff.c         | 17 +++++++++++++++++ | ||||||
|  |  net/ethernet/eth.c        |  6 ++++++ | ||||||
|  |  6 files changed, 58 insertions(+), 14 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/include/linux/netdevice.h | ||||||
|  | +++ b/include/linux/netdevice.h | ||||||
|  | @@ -1386,6 +1386,7 @@ enum netdev_priv_flags { | ||||||
|  |  	IFF_RXFH_CONFIGURED		= 1<<25, | ||||||
|  |  	IFF_PHONY_HEADROOM		= 1<<26, | ||||||
|  |  	IFF_MACSEC			= 1<<27, | ||||||
|  | +	IFF_NO_IP_ALIGN			= 1<<28, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  #define IFF_802_1Q_VLAN			IFF_802_1Q_VLAN | ||||||
|  | @@ -1415,6 +1416,7 @@ enum netdev_priv_flags { | ||||||
|  |  #define IFF_TEAM			IFF_TEAM | ||||||
|  |  #define IFF_RXFH_CONFIGURED		IFF_RXFH_CONFIGURED | ||||||
|  |  #define IFF_MACSEC			IFF_MACSEC | ||||||
|  | +#define IFF_NO_IP_ALIGN			IFF_NO_IP_ALIGN | ||||||
|  |   | ||||||
|  |  /** | ||||||
|  |   *	struct net_device - The DEVICE structure. | ||||||
|  | @@ -1701,6 +1703,11 @@ struct net_device { | ||||||
|  |  	const struct xfrmdev_ops *xfrmdev_ops; | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  | +#ifdef CONFIG_ETHERNET_PACKET_MANGLE | ||||||
|  | +	void (*eth_mangle_rx)(struct net_device *dev, struct sk_buff *skb); | ||||||
|  | +	struct sk_buff *(*eth_mangle_tx)(struct net_device *dev, struct sk_buff *skb); | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  |  	const struct header_ops *header_ops; | ||||||
|  |   | ||||||
|  |  	unsigned int		flags; | ||||||
|  | @@ -1770,6 +1777,10 @@ struct net_device { | ||||||
|  |  	struct mpls_dev __rcu	*mpls_ptr; | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  | +#ifdef CONFIG_ETHERNET_PACKET_MANGLE | ||||||
|  | +	void			*phy_ptr; /* PHY device specific data */ | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  |  /* | ||||||
|  |   * Cache lines mostly used on receive path (including eth_type_trans()) | ||||||
|  |   */ | ||||||
|  | --- a/include/linux/skbuff.h | ||||||
|  | +++ b/include/linux/skbuff.h | ||||||
|  | @@ -2492,6 +2492,10 @@ static inline int pskb_trim(struct sk_bu | ||||||
|  |  	return (len < skb->len) ? __pskb_trim(skb, len) : 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, | ||||||
|  | +		unsigned int length, gfp_t gfp); | ||||||
|  | + | ||||||
|  | + | ||||||
|  |  /** | ||||||
|  |   *	pskb_trim_unique - remove end from a paged unique (not cloned) buffer | ||||||
|  |   *	@skb: buffer to alter | ||||||
|  | @@ -2622,16 +2626,6 @@ static inline struct sk_buff *dev_alloc_ | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |   | ||||||
|  | -static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, | ||||||
|  | -		unsigned int length, gfp_t gfp) | ||||||
|  | -{ | ||||||
|  | -	struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp); | ||||||
|  | - | ||||||
|  | -	if (NET_IP_ALIGN && skb) | ||||||
|  | -		skb_reserve(skb, NET_IP_ALIGN); | ||||||
|  | -	return skb; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  |  static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, | ||||||
|  |  		unsigned int length) | ||||||
|  |  { | ||||||
|  | --- a/net/Kconfig | ||||||
|  | +++ b/net/Kconfig | ||||||
|  | @@ -25,6 +25,12 @@ menuconfig NET | ||||||
|  |   | ||||||
|  |  if NET | ||||||
|  |   | ||||||
|  | +config ETHERNET_PACKET_MANGLE | ||||||
|  | +	bool | ||||||
|  | +	help | ||||||
|  | +	  This option can be selected by phy drivers that need to mangle | ||||||
|  | +	  packets going in or out of an ethernet device. | ||||||
|  | + | ||||||
|  |  config WANT_COMPAT_NETLINK_MESSAGES | ||||||
|  |  	bool | ||||||
|  |  	help | ||||||
|  | --- a/net/core/dev.c | ||||||
|  | +++ b/net/core/dev.c | ||||||
|  | @@ -2974,10 +2974,20 @@ static int xmit_one(struct sk_buff *skb, | ||||||
|  |  	if (!list_empty(&ptype_all) || !list_empty(&dev->ptype_all)) | ||||||
|  |  		dev_queue_xmit_nit(skb, dev); | ||||||
|  |   | ||||||
|  | -	len = skb->len; | ||||||
|  | -	trace_net_dev_start_xmit(skb, dev); | ||||||
|  | -	rc = netdev_start_xmit(skb, dev, txq, more); | ||||||
|  | -	trace_net_dev_xmit(skb, rc, dev, len); | ||||||
|  | +#ifdef CONFIG_ETHERNET_PACKET_MANGLE | ||||||
|  | +	if (!dev->eth_mangle_tx || | ||||||
|  | +	    (skb = dev->eth_mangle_tx(dev, skb)) != NULL) | ||||||
|  | +#else | ||||||
|  | +	if (1) | ||||||
|  | +#endif | ||||||
|  | +	{ | ||||||
|  | +		len = skb->len; | ||||||
|  | +		trace_net_dev_start_xmit(skb, dev); | ||||||
|  | +		rc = netdev_start_xmit(skb, dev, txq, more); | ||||||
|  | +		trace_net_dev_xmit(skb, rc, dev, len); | ||||||
|  | +	} else { | ||||||
|  | +		rc = NETDEV_TX_OK; | ||||||
|  | +	} | ||||||
|  |   | ||||||
|  |  	return rc; | ||||||
|  |  } | ||||||
|  | --- a/net/core/skbuff.c | ||||||
|  | +++ b/net/core/skbuff.c | ||||||
|  | @@ -64,6 +64,7 @@ | ||||||
|  |  #include <linux/errqueue.h> | ||||||
|  |  #include <linux/prefetch.h> | ||||||
|  |  #include <linux/if_vlan.h> | ||||||
|  | +#include <linux/if.h> | ||||||
|  |   | ||||||
|  |  #include <net/protocol.h> | ||||||
|  |  #include <net/dst.h> | ||||||
|  | @@ -503,6 +504,22 @@ skb_fail: | ||||||
|  |  } | ||||||
|  |  EXPORT_SYMBOL(__napi_alloc_skb); | ||||||
|  |   | ||||||
|  | +struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev, | ||||||
|  | +		unsigned int length, gfp_t gfp) | ||||||
|  | +{ | ||||||
|  | +	struct sk_buff *skb = __netdev_alloc_skb(dev, length + NET_IP_ALIGN, gfp); | ||||||
|  | + | ||||||
|  | +#ifdef CONFIG_ETHERNET_PACKET_MANGLE | ||||||
|  | +	if (dev && (dev->priv_flags & IFF_NO_IP_ALIGN)) | ||||||
|  | +		return skb; | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  | +	if (NET_IP_ALIGN && skb) | ||||||
|  | +		skb_reserve(skb, NET_IP_ALIGN); | ||||||
|  | +	return skb; | ||||||
|  | +} | ||||||
|  | +EXPORT_SYMBOL(__netdev_alloc_skb_ip_align); | ||||||
|  | + | ||||||
|  |  void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, | ||||||
|  |  		     int size, unsigned int truesize) | ||||||
|  |  { | ||||||
|  | --- a/net/ethernet/eth.c | ||||||
|  | +++ b/net/ethernet/eth.c | ||||||
|  | @@ -172,6 +172,12 @@ __be16 eth_type_trans(struct sk_buff *sk | ||||||
|  |  	const struct ethhdr *eth; | ||||||
|  |   | ||||||
|  |  	skb->dev = dev; | ||||||
|  | + | ||||||
|  | +#ifdef CONFIG_ETHERNET_PACKET_MANGLE | ||||||
|  | +	if (dev->eth_mangle_rx) | ||||||
|  | +		dev->eth_mangle_rx(dev, skb); | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  |  	skb_reset_mac_header(skb); | ||||||
|  |   | ||||||
|  |  	eth = (struct ethhdr *)skb->data; | ||||||
| @@ -0,0 +1,98 @@ | |||||||
|  | From 3cb240533ab787899dc7f17aa7d6c5b4810e2e58 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Hauke Mehrtens <hauke@hauke-m.de> | ||||||
|  | Date: Fri, 7 Jul 2017 17:26:01 +0200 | ||||||
|  | Subject: bcm53xx: bgmac: use srab switch driver | ||||||
|  |  | ||||||
|  | use the srab switch driver on these SoCs. | ||||||
|  |  | ||||||
|  | Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> | ||||||
|  | --- | ||||||
|  |  drivers/net/ethernet/broadcom/bgmac-bcma.c |  1 + | ||||||
|  |  drivers/net/ethernet/broadcom/bgmac.c      | 24 ++++++++++++++++++++++++ | ||||||
|  |  drivers/net/ethernet/broadcom/bgmac.h      |  4 ++++ | ||||||
|  |  3 files changed, 29 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/ethernet/broadcom/bgmac-bcma.c | ||||||
|  | +++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c | ||||||
|  | @@ -268,6 +268,7 @@ static int bgmac_probe(struct bcma_devic | ||||||
|  |  		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; | ||||||
|  |  		bgmac->feature_flags |= BGMAC_FEAT_NO_RESET; | ||||||
|  |  		bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500; | ||||||
|  | +		bgmac->feature_flags |= BGMAC_FEAT_SRAB; | ||||||
|  |  		break; | ||||||
|  |  	default: | ||||||
|  |  		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; | ||||||
|  | --- a/drivers/net/ethernet/broadcom/bgmac.c | ||||||
|  | +++ b/drivers/net/ethernet/broadcom/bgmac.c | ||||||
|  | @@ -12,6 +12,7 @@ | ||||||
|  |  #include <linux/bcma/bcma.h> | ||||||
|  |  #include <linux/etherdevice.h> | ||||||
|  |  #include <linux/interrupt.h> | ||||||
|  | +#include <linux/platform_data/b53.h> | ||||||
|  |  #include <linux/bcm47xx_nvram.h> | ||||||
|  |  #include <linux/phy.h> | ||||||
|  |  #include <linux/phy_fixed.h> | ||||||
|  | @@ -1409,6 +1410,17 @@ static const struct ethtool_ops bgmac_et | ||||||
|  |  	.set_link_ksettings     = phy_ethtool_set_link_ksettings, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +static struct b53_platform_data bgmac_b53_pdata = { | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +static struct platform_device bgmac_b53_dev = { | ||||||
|  | +	.name		= "b53-srab-switch", | ||||||
|  | +	.id		= -1, | ||||||
|  | +	.dev		= { | ||||||
|  | +		.platform_data = &bgmac_b53_pdata, | ||||||
|  | +	}, | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  |  /************************************************** | ||||||
|  |   * MII | ||||||
|  |   **************************************************/ | ||||||
|  | @@ -1538,6 +1550,14 @@ int bgmac_enet_probe(struct bgmac *bgmac | ||||||
|  |  	net_dev->hw_features = net_dev->features; | ||||||
|  |  	net_dev->vlan_features = net_dev->features; | ||||||
|  |   | ||||||
|  | +	if ((bgmac->feature_flags & BGMAC_FEAT_SRAB) && !bgmac_b53_pdata.regs) { | ||||||
|  | +		bgmac_b53_pdata.regs = ioremap_nocache(0x18007000, 0x1000); | ||||||
|  | + | ||||||
|  | +		err = platform_device_register(&bgmac_b53_dev); | ||||||
|  | +		if (!err) | ||||||
|  | +			bgmac->b53_device = &bgmac_b53_dev; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	err = register_netdev(bgmac->net_dev); | ||||||
|  |  	if (err) { | ||||||
|  |  		dev_err(bgmac->dev, "Cannot register net device\n"); | ||||||
|  | @@ -1560,6 +1580,10 @@ EXPORT_SYMBOL_GPL(bgmac_enet_probe); | ||||||
|  |   | ||||||
|  |  void bgmac_enet_remove(struct bgmac *bgmac) | ||||||
|  |  { | ||||||
|  | +	if (bgmac->b53_device) | ||||||
|  | +		platform_device_unregister(&bgmac_b53_dev); | ||||||
|  | +	bgmac->b53_device = NULL; | ||||||
|  | + | ||||||
|  |  	unregister_netdev(bgmac->net_dev); | ||||||
|  |  	phy_disconnect(bgmac->net_dev->phydev); | ||||||
|  |  	netif_napi_del(&bgmac->napi); | ||||||
|  | --- a/drivers/net/ethernet/broadcom/bgmac.h | ||||||
|  | +++ b/drivers/net/ethernet/broadcom/bgmac.h | ||||||
|  | @@ -427,6 +427,7 @@ | ||||||
|  |  #define BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII	BIT(18) | ||||||
|  |  #define BGMAC_FEAT_CC7_IF_TYPE_RGMII	BIT(19) | ||||||
|  |  #define BGMAC_FEAT_IDM_MASK		BIT(20) | ||||||
|  | +#define BGMAC_FEAT_SRAB			BIT(21) | ||||||
|  |   | ||||||
|  |  struct bgmac_slot_info { | ||||||
|  |  	union { | ||||||
|  | @@ -532,6 +533,9 @@ struct bgmac { | ||||||
|  |  	void (*cmn_maskset32)(struct bgmac *bgmac, u16 offset, u32 mask, | ||||||
|  |  			      u32 set); | ||||||
|  |  	int (*phy_connect)(struct bgmac *bgmac); | ||||||
|  | + | ||||||
|  | +	/* platform device for associated switch */ | ||||||
|  | +	struct platform_device *b53_device; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  struct bgmac *bgmac_alloc(struct device *dev); | ||||||
							
								
								
									
										52
									
								
								target/linux/generic/hack-4.14/835-misc-owl_loader.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								target/linux/generic/hack-4.14/835-misc-owl_loader.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | |||||||
|  | From dd36f935973d91644449bd9749f6062a2bed821b Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Christian Lamparter <chunkeey@googlemail.com> | ||||||
|  | Date: Fri, 7 Jul 2017 17:26:46 +0200 | ||||||
|  | Subject: misc: owl-loader for delayed Atheros ath9k fixup | ||||||
|  |  | ||||||
|  | Some devices (like the Cisco Meraki Z1 Cloud Managed Teleworker Gateway) | ||||||
|  | need to be able to initialize the PCIe wifi device. Normally, this is done | ||||||
|  | during the early stages of booting linux, because the necessary init code | ||||||
|  | is read from the memory mapped SPI and passed to pci_enable_ath9k_fixup. | ||||||
|  | However,this isn't possible for devices which have the init code for the | ||||||
|  | Atheros chip stored on NAND in an UBI volume. Hence, this module can be | ||||||
|  | used to initialze the chip when the user-space is ready to extract the | ||||||
|  | init code. | ||||||
|  |  | ||||||
|  | Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> | ||||||
|  | Signed-off-by: Christian Lamparter <chunkeey@googlemail.com> | ||||||
|  | --- | ||||||
|  |  drivers/misc/Kconfig  | 12 ++++++++++++ | ||||||
|  |  drivers/misc/Makefile |  1 + | ||||||
|  |  2 files changed, 13 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/misc/Kconfig | ||||||
|  | +++ b/drivers/misc/Kconfig | ||||||
|  | @@ -151,6 +151,18 @@ config SGI_IOC4 | ||||||
|  |  	  If you have an SGI Altix with an IOC4-based card say Y. | ||||||
|  |  	  Otherwise say N. | ||||||
|  |   | ||||||
|  | +config OWL_LOADER | ||||||
|  | +	tristate "Owl loader for initializing Atheros PCI(e) Wifi chips" | ||||||
|  | +	depends on PCI | ||||||
|  | +	---help--- | ||||||
|  | +	This kernel module helps to initialize certain Qualcomm | ||||||
|  | +	Atheros' PCI(e) Wifi chips, which have the init data | ||||||
|  | +	(which contains the PCI device ID for example) stored | ||||||
|  | +	together with the calibration data in the file system. | ||||||
|  | + | ||||||
|  | +	This is necessary for devices like the Cisco Meraki Z1, say M. | ||||||
|  | +	Otherwise say N. | ||||||
|  | + | ||||||
|  |  config TIFM_CORE | ||||||
|  |  	tristate "TI Flash Media interface support" | ||||||
|  |  	depends on PCI | ||||||
|  | --- a/drivers/misc/Makefile | ||||||
|  | +++ b/drivers/misc/Makefile | ||||||
|  | @@ -13,6 +13,7 @@ obj-$(CONFIG_ATMEL_TCLIB)	+= atmel_tclib | ||||||
|  |  obj-$(CONFIG_DUMMY_IRQ)		+= dummy-irq.o | ||||||
|  |  obj-$(CONFIG_ICS932S401)	+= ics932s401.o | ||||||
|  |  obj-$(CONFIG_LKDTM)		+= lkdtm.o | ||||||
|  | +obj-$(CONFIG_OWL_LOADER)	+= owl-loader.o | ||||||
|  |  obj-$(CONFIG_TIFM_CORE)       	+= tifm_core.o | ||||||
|  |  obj-$(CONFIG_TIFM_7XX1)       	+= tifm_7xx1.o | ||||||
|  |  obj-$(CONFIG_PHANTOM)		+= phantom.o | ||||||
							
								
								
									
										136
									
								
								target/linux/generic/hack-4.14/901-debloat_sock_diag.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								target/linux/generic/hack-4.14/901-debloat_sock_diag.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | |||||||
|  | From 3b6115d6b57a263bdc8c9b1df273bd4a7955eead Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Sat, 8 Jul 2017 08:16:31 +0200 | ||||||
|  | Subject: debloat: add some debloat patches, strip down procfs and make O_DIRECT support optional, saves ~15K after lzma on MIPS | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  net/Kconfig         | 3 +++ | ||||||
|  |  net/core/Makefile   | 3 ++- | ||||||
|  |  net/core/sock.c     | 2 ++ | ||||||
|  |  net/ipv4/Kconfig    | 1 + | ||||||
|  |  net/netlink/Kconfig | 1 + | ||||||
|  |  net/packet/Kconfig  | 1 + | ||||||
|  |  net/unix/Kconfig    | 1 + | ||||||
|  |  7 files changed, 11 insertions(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/net/Kconfig | ||||||
|  | +++ b/net/Kconfig | ||||||
|  | @@ -97,6 +97,9 @@ source "net/netlabel/Kconfig" | ||||||
|  |   | ||||||
|  |  endif # if INET | ||||||
|  |   | ||||||
|  | +config SOCK_DIAG | ||||||
|  | +	bool | ||||||
|  | + | ||||||
|  |  config NETWORK_SECMARK | ||||||
|  |  	bool "Security Marking" | ||||||
|  |  	help | ||||||
|  | --- a/net/core/Makefile | ||||||
|  | +++ b/net/core/Makefile | ||||||
|  | @@ -10,9 +10,10 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core. | ||||||
|  |   | ||||||
|  |  obj-y		     += dev.o ethtool.o dev_addr_lists.o dst.o netevent.o \ | ||||||
|  |  			neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ | ||||||
|  | -			sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \ | ||||||
|  | + 			dev_ioctl.o tso.o sock_reuseport.o \ | ||||||
|  |  			fib_notifier.o | ||||||
|  |   | ||||||
|  | +obj-$(CONFIG_SOCK_DIAG) += sock_diag.o  | ||||||
|  |  obj-y += net-sysfs.o | ||||||
|  |  obj-$(CONFIG_PROC_FS) += net-procfs.o | ||||||
|  |  obj-$(CONFIG_NET_PKTGEN) += pktgen.o | ||||||
|  | --- a/net/core/sock.c | ||||||
|  | +++ b/net/core/sock.c | ||||||
|  | @@ -528,6 +528,18 @@ discard_and_relse: | ||||||
|  |  } | ||||||
|  |  EXPORT_SYMBOL(__sk_receive_skb); | ||||||
|  |   | ||||||
|  | +u64 sock_gen_cookie(struct sock *sk) | ||||||
|  | +{ | ||||||
|  | +	while (1) { | ||||||
|  | +		u64 res = atomic64_read(&sk->sk_cookie); | ||||||
|  | + | ||||||
|  | +		if (res) | ||||||
|  | +			return res; | ||||||
|  | +		res = atomic64_inc_return(&sock_net(sk)->cookie_gen); | ||||||
|  | +		atomic64_cmpxchg(&sk->sk_cookie, 0, res); | ||||||
|  | +	} | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie) | ||||||
|  |  { | ||||||
|  |  	struct dst_entry *dst = __sk_dst_get(sk); | ||||||
|  | @@ -1597,9 +1609,11 @@ void sk_destruct(struct sock *sk) | ||||||
|  |   | ||||||
|  |  static void __sk_free(struct sock *sk) | ||||||
|  |  { | ||||||
|  | +#ifdef CONFIG_SOCK_DIAG | ||||||
|  |  	if (unlikely(sock_diag_has_destroy_listeners(sk) && sk->sk_net_refcnt)) | ||||||
|  |  		sock_diag_broadcast_destroy(sk); | ||||||
|  |  	else | ||||||
|  | +#endif | ||||||
|  |  		sk_destruct(sk); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | --- a/net/core/sock_diag.c | ||||||
|  | +++ b/net/core/sock_diag.c | ||||||
|  | @@ -19,18 +19,6 @@ static int (*inet_rcv_compat)(struct sk_ | ||||||
|  |  static DEFINE_MUTEX(sock_diag_table_mutex); | ||||||
|  |  static struct workqueue_struct *broadcast_wq; | ||||||
|  |   | ||||||
|  | -u64 sock_gen_cookie(struct sock *sk) | ||||||
|  | -{ | ||||||
|  | -	while (1) { | ||||||
|  | -		u64 res = atomic64_read(&sk->sk_cookie); | ||||||
|  | - | ||||||
|  | -		if (res) | ||||||
|  | -			return res; | ||||||
|  | -		res = atomic64_inc_return(&sock_net(sk)->cookie_gen); | ||||||
|  | -		atomic64_cmpxchg(&sk->sk_cookie, 0, res); | ||||||
|  | -	} | ||||||
|  | -} | ||||||
|  | - | ||||||
|  |  int sock_diag_check_cookie(struct sock *sk, const __u32 *cookie) | ||||||
|  |  { | ||||||
|  |  	u64 res; | ||||||
|  | --- a/net/ipv4/Kconfig | ||||||
|  | +++ b/net/ipv4/Kconfig | ||||||
|  | @@ -420,6 +420,7 @@ config INET_XFRM_MODE_BEET | ||||||
|  |   | ||||||
|  |  config INET_DIAG | ||||||
|  |  	tristate "INET: socket monitoring interface" | ||||||
|  | +	select SOCK_DIAG | ||||||
|  |  	default y | ||||||
|  |  	---help--- | ||||||
|  |  	  Support for INET (TCP, DCCP, etc) socket monitoring interface used by | ||||||
|  | --- a/net/netlink/Kconfig | ||||||
|  | +++ b/net/netlink/Kconfig | ||||||
|  | @@ -4,6 +4,7 @@ | ||||||
|  |   | ||||||
|  |  config NETLINK_DIAG | ||||||
|  |  	tristate "NETLINK: socket monitoring interface" | ||||||
|  | +	select SOCK_DIAG | ||||||
|  |  	default n | ||||||
|  |  	---help--- | ||||||
|  |  	  Support for NETLINK socket monitoring interface used by the ss tool. | ||||||
|  | --- a/net/packet/Kconfig | ||||||
|  | +++ b/net/packet/Kconfig | ||||||
|  | @@ -18,6 +18,7 @@ config PACKET | ||||||
|  |  config PACKET_DIAG | ||||||
|  |  	tristate "Packet: sockets monitoring interface" | ||||||
|  |  	depends on PACKET | ||||||
|  | +	select SOCK_DIAG | ||||||
|  |  	default n | ||||||
|  |  	---help--- | ||||||
|  |  	  Support for PF_PACKET sockets monitoring interface used by the ss tool. | ||||||
|  | --- a/net/unix/Kconfig | ||||||
|  | +++ b/net/unix/Kconfig | ||||||
|  | @@ -22,6 +22,7 @@ config UNIX | ||||||
|  |  config UNIX_DIAG | ||||||
|  |  	tristate "UNIX: socket monitoring interface" | ||||||
|  |  	depends on UNIX | ||||||
|  | +	select SOCK_DIAG | ||||||
|  |  	default n | ||||||
|  |  	---help--- | ||||||
|  |  	  Support for UNIX socket monitoring interface used by the ss tool. | ||||||
							
								
								
									
										405
									
								
								target/linux/generic/hack-4.14/902-debloat_proc.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										405
									
								
								target/linux/generic/hack-4.14/902-debloat_proc.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,405 @@ | |||||||
|  | From 9e3f1d0805b2d919904dd9a4ff0d956314cc3cba Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Sat, 8 Jul 2017 08:20:09 +0200 | ||||||
|  | Subject: debloat: procfs | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  fs/locks.c               |  2 ++ | ||||||
|  |  fs/proc/Kconfig          |  5 +++++ | ||||||
|  |  fs/proc/consoles.c       |  3 +++ | ||||||
|  |  fs/proc/proc_tty.c       | 11 ++++++++++- | ||||||
|  |  include/net/snmp.h       | 18 +++++++++++++++++- | ||||||
|  |  ipc/msg.c                |  3 +++ | ||||||
|  |  ipc/sem.c                |  2 ++ | ||||||
|  |  ipc/shm.c                |  2 ++ | ||||||
|  |  ipc/util.c               |  3 +++ | ||||||
|  |  kernel/exec_domain.c     |  2 ++ | ||||||
|  |  kernel/irq/proc.c        |  9 +++++++++ | ||||||
|  |  kernel/time/timer_list.c |  2 ++ | ||||||
|  |  mm/vmalloc.c             |  2 ++ | ||||||
|  |  mm/vmstat.c              |  8 +++++--- | ||||||
|  |  net/8021q/vlanproc.c     |  6 ++++++ | ||||||
|  |  net/core/net-procfs.c    | 18 ++++++++++++------ | ||||||
|  |  net/core/sock.c          |  2 ++ | ||||||
|  |  net/ipv4/fib_trie.c      | 18 ++++++++++++------ | ||||||
|  |  net/ipv4/proc.c          |  3 +++ | ||||||
|  |  net/ipv4/route.c         |  3 +++ | ||||||
|  |  20 files changed, 105 insertions(+), 17 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/fs/locks.c | ||||||
|  | +++ b/fs/locks.c | ||||||
|  | @@ -2805,6 +2805,8 @@ static const struct file_operations proc | ||||||
|  |   | ||||||
|  |  static int __init proc_locks_init(void) | ||||||
|  |  { | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return 0; | ||||||
|  |  	proc_create("locks", 0, NULL, &proc_locks_operations); | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  | --- a/fs/proc/Kconfig | ||||||
|  | +++ b/fs/proc/Kconfig | ||||||
|  | @@ -81,3 +81,8 @@ config PROC_CHILDREN | ||||||
|  |   | ||||||
|  |  	  Say Y if you are running any user-space software which takes benefit from | ||||||
|  |  	  this interface. For example, rkt is such a piece of software. | ||||||
|  | + | ||||||
|  | +config PROC_STRIPPED | ||||||
|  | +	default n | ||||||
|  | +	depends on EXPERT | ||||||
|  | +	bool "Strip non-essential /proc functionality to reduce code size" | ||||||
|  | --- a/fs/proc/consoles.c | ||||||
|  | +++ b/fs/proc/consoles.c | ||||||
|  | @@ -106,6 +106,9 @@ static const struct file_operations proc | ||||||
|  |   | ||||||
|  |  static int __init proc_consoles_init(void) | ||||||
|  |  { | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  |  	proc_create("consoles", 0, NULL, &proc_consoles_operations); | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  | --- a/fs/proc/proc_tty.c | ||||||
|  | +++ b/fs/proc/proc_tty.c | ||||||
|  | @@ -144,7 +144,10 @@ static const struct file_operations proc | ||||||
|  |  void proc_tty_register_driver(struct tty_driver *driver) | ||||||
|  |  { | ||||||
|  |  	struct proc_dir_entry *ent; | ||||||
|  | -		 | ||||||
|  | + | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  |  	if (!driver->driver_name || driver->proc_entry || | ||||||
|  |  	    !driver->ops->proc_fops) | ||||||
|  |  		return; | ||||||
|  | @@ -161,6 +164,9 @@ void proc_tty_unregister_driver(struct t | ||||||
|  |  { | ||||||
|  |  	struct proc_dir_entry *ent; | ||||||
|  |   | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  |  	ent = driver->proc_entry; | ||||||
|  |  	if (!ent) | ||||||
|  |  		return; | ||||||
|  | @@ -175,6 +181,9 @@ void proc_tty_unregister_driver(struct t | ||||||
|  |   */ | ||||||
|  |  void __init proc_tty_init(void) | ||||||
|  |  { | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  |  	if (!proc_mkdir("tty", NULL)) | ||||||
|  |  		return; | ||||||
|  |  	proc_mkdir("tty/ldisc", NULL);	/* Preserved: it's userspace visible */ | ||||||
|  | --- a/include/net/snmp.h | ||||||
|  | +++ b/include/net/snmp.h | ||||||
|  | @@ -123,6 +123,21 @@ struct linux_xfrm_mib { | ||||||
|  |  #define DECLARE_SNMP_STAT(type, name)	\ | ||||||
|  |  	extern __typeof__(type) __percpu *name | ||||||
|  |   | ||||||
|  | +#ifdef CONFIG_PROC_STRIPPED | ||||||
|  | +#define __SNMP_STATS_DUMMY(mib)	\ | ||||||
|  | +	do { (void) mib->mibs[0]; } while(0) | ||||||
|  | + | ||||||
|  | +#define __SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib) | ||||||
|  | +#define SNMP_INC_STATS_ATOMIC_LONG(mib, field) __SNMP_STATS_DUMMY(mib) | ||||||
|  | +#define SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib) | ||||||
|  | +#define SNMP_DEC_STATS(mib, field) __SNMP_STATS_DUMMY(mib) | ||||||
|  | +#define __SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib) | ||||||
|  | +#define SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib) | ||||||
|  | +#define SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib) | ||||||
|  | +#define __SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib) | ||||||
|  | + | ||||||
|  | +#else | ||||||
|  | + | ||||||
|  |  #define __SNMP_INC_STATS(mib, field)	\ | ||||||
|  |  			__this_cpu_inc(mib->mibs[field]) | ||||||
|  |   | ||||||
|  | @@ -153,8 +168,9 @@ struct linux_xfrm_mib { | ||||||
|  |  		__this_cpu_add(ptr[basefield##OCTETS], addend);	\ | ||||||
|  |  	} while (0) | ||||||
|  |   | ||||||
|  | +#endif | ||||||
|  |   | ||||||
|  | -#if BITS_PER_LONG==32 | ||||||
|  | +#if (BITS_PER_LONG==32) && !defined(CONFIG_PROC_STRIPPED) | ||||||
|  |   | ||||||
|  |  #define __SNMP_ADD_STATS64(mib, field, addend) 				\ | ||||||
|  |  	do {								\ | ||||||
|  | --- a/ipc/msg.c | ||||||
|  | +++ b/ipc/msg.c | ||||||
|  | @@ -1208,6 +1208,9 @@ int __init msg_init(void) | ||||||
|  |  { | ||||||
|  |  	const int err = msg_init_ns(&init_ipc_ns); | ||||||
|  |   | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return err; | ||||||
|  | + | ||||||
|  |  	ipc_init_proc_interface("sysvipc/msg", | ||||||
|  |  				"       key      msqid perms      cbytes       qnum lspid lrpid   uid   gid  cuid  cgid      stime      rtime      ctime\n", | ||||||
|  |  				IPC_MSG_IDS, sysvipc_msg_proc_show); | ||||||
|  | --- a/ipc/sem.c | ||||||
|  | +++ b/ipc/sem.c | ||||||
|  | @@ -207,6 +207,8 @@ int __init sem_init(void) | ||||||
|  |  { | ||||||
|  |  	const int err = sem_init_ns(&init_ipc_ns); | ||||||
|  |   | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return err; | ||||||
|  |  	ipc_init_proc_interface("sysvipc/sem", | ||||||
|  |  				"       key      semid perms      nsems   uid   gid  cuid  cgid      otime      ctime\n", | ||||||
|  |  				IPC_SEM_IDS, sysvipc_sem_proc_show); | ||||||
|  | --- a/ipc/shm.c | ||||||
|  | +++ b/ipc/shm.c | ||||||
|  | @@ -122,6 +122,8 @@ pure_initcall(ipc_ns_init); | ||||||
|  |   | ||||||
|  |  void __init shm_init(void) | ||||||
|  |  { | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return; | ||||||
|  |  	ipc_init_proc_interface("sysvipc/shm", | ||||||
|  |  #if BITS_PER_LONG <= 32 | ||||||
|  |  				"       key      shmid perms       size  cpid  lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime        rss       swap\n", | ||||||
|  | --- a/ipc/util.c | ||||||
|  | +++ b/ipc/util.c | ||||||
|  | @@ -141,6 +141,9 @@ void __init ipc_init_proc_interface(cons | ||||||
|  |  	struct proc_dir_entry *pde; | ||||||
|  |  	struct ipc_proc_iface *iface; | ||||||
|  |   | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  |  	iface = kmalloc(sizeof(*iface), GFP_KERNEL); | ||||||
|  |  	if (!iface) | ||||||
|  |  		return; | ||||||
|  | --- a/kernel/exec_domain.c | ||||||
|  | +++ b/kernel/exec_domain.c | ||||||
|  | @@ -42,6 +42,8 @@ static const struct file_operations exec | ||||||
|  |   | ||||||
|  |  static int __init proc_execdomains_init(void) | ||||||
|  |  { | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return 0; | ||||||
|  |  	proc_create("execdomains", 0, NULL, &execdomains_proc_fops); | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  | --- a/kernel/irq/proc.c | ||||||
|  | +++ b/kernel/irq/proc.c | ||||||
|  | @@ -396,6 +396,9 @@ void register_irq_proc(unsigned int irq, | ||||||
|  |  	void __maybe_unused *irqp = (void *)(unsigned long) irq; | ||||||
|  |  	char name [MAX_NAMELEN]; | ||||||
|  |   | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  |  	if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip)) | ||||||
|  |  		return; | ||||||
|  |   | ||||||
|  | @@ -449,6 +452,9 @@ void unregister_irq_proc(unsigned int ir | ||||||
|  |  { | ||||||
|  |  	char name [MAX_NAMELEN]; | ||||||
|  |   | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  |  	if (!root_irq_dir || !desc->dir) | ||||||
|  |  		return; | ||||||
|  |  #ifdef CONFIG_SMP | ||||||
|  | @@ -487,6 +493,9 @@ void init_irq_proc(void) | ||||||
|  |  	unsigned int irq; | ||||||
|  |  	struct irq_desc *desc; | ||||||
|  |   | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP)) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  |  	/* create /proc/irq */ | ||||||
|  |  	root_irq_dir = proc_mkdir("irq", NULL); | ||||||
|  |  	if (!root_irq_dir) | ||||||
|  | --- a/kernel/time/timer_list.c | ||||||
|  | +++ b/kernel/time/timer_list.c | ||||||
|  | @@ -389,6 +389,8 @@ static int __init init_timer_list_procfs | ||||||
|  |  { | ||||||
|  |  	struct proc_dir_entry *pe; | ||||||
|  |   | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return 0; | ||||||
|  |  	pe = proc_create("timer_list", 0444, NULL, &timer_list_fops); | ||||||
|  |  	if (!pe) | ||||||
|  |  		return -ENOMEM; | ||||||
|  | --- a/mm/vmalloc.c | ||||||
|  | +++ b/mm/vmalloc.c | ||||||
|  | @@ -2765,6 +2765,8 @@ static const struct file_operations proc | ||||||
|  |   | ||||||
|  |  static int __init proc_vmalloc_init(void) | ||||||
|  |  { | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return 0; | ||||||
|  |  	proc_create("vmallocinfo", S_IRUSR, NULL, &proc_vmalloc_operations); | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  | --- a/mm/vmstat.c | ||||||
|  | +++ b/mm/vmstat.c | ||||||
|  | @@ -1944,10 +1944,12 @@ void __init init_mm_internals(void) | ||||||
|  |  	start_shepherd_timer(); | ||||||
|  |  #endif | ||||||
|  |  #ifdef CONFIG_PROC_FS | ||||||
|  | -	proc_create("buddyinfo", 0444, NULL, &buddyinfo_file_operations); | ||||||
|  | -	proc_create("pagetypeinfo", 0444, NULL, &pagetypeinfo_file_operations); | ||||||
|  | +	if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { | ||||||
|  | +		proc_create("buddyinfo", 0444, NULL, &buddyinfo_file_operations); | ||||||
|  | +		proc_create("pagetypeinfo", 0444, NULL, &pagetypeinfo_file_operations); | ||||||
|  | +		proc_create("zoneinfo", 0444, NULL, &zoneinfo_file_operations); | ||||||
|  | +	} | ||||||
|  |  	proc_create("vmstat", 0444, NULL, &vmstat_file_operations); | ||||||
|  | -	proc_create("zoneinfo", 0444, NULL, &zoneinfo_file_operations); | ||||||
|  |  #endif | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | --- a/net/8021q/vlanproc.c | ||||||
|  | +++ b/net/8021q/vlanproc.c | ||||||
|  | @@ -127,6 +127,9 @@ void vlan_proc_cleanup(struct net *net) | ||||||
|  |  { | ||||||
|  |  	struct vlan_net *vn = net_generic(net, vlan_net_id); | ||||||
|  |   | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  |  	if (vn->proc_vlan_conf) | ||||||
|  |  		remove_proc_entry(name_conf, vn->proc_vlan_dir); | ||||||
|  |   | ||||||
|  | @@ -146,6 +149,9 @@ int __net_init vlan_proc_init(struct net | ||||||
|  |  { | ||||||
|  |  	struct vlan_net *vn = net_generic(net, vlan_net_id); | ||||||
|  |   | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  |  	vn->proc_vlan_dir = proc_net_mkdir(net, name_root, net->proc_net); | ||||||
|  |  	if (!vn->proc_vlan_dir) | ||||||
|  |  		goto err; | ||||||
|  | --- a/net/core/net-procfs.c | ||||||
|  | +++ b/net/core/net-procfs.c | ||||||
|  | @@ -320,10 +320,12 @@ static int __net_init dev_proc_net_init( | ||||||
|  |   | ||||||
|  |  	if (!proc_create("dev", S_IRUGO, net->proc_net, &dev_seq_fops)) | ||||||
|  |  		goto out; | ||||||
|  | -	if (!proc_create("softnet_stat", S_IRUGO, net->proc_net, | ||||||
|  | +	if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && | ||||||
|  | +		!proc_create("softnet_stat", S_IRUGO, net->proc_net, | ||||||
|  |  			 &softnet_seq_fops)) | ||||||
|  |  		goto out_dev; | ||||||
|  | -	if (!proc_create("ptype", S_IRUGO, net->proc_net, &ptype_seq_fops)) | ||||||
|  | +	if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && | ||||||
|  | +		!proc_create("ptype", S_IRUGO, net->proc_net, &ptype_seq_fops)) | ||||||
|  |  		goto out_softnet; | ||||||
|  |   | ||||||
|  |  	if (wext_proc_init(net)) | ||||||
|  | @@ -332,9 +334,11 @@ static int __net_init dev_proc_net_init( | ||||||
|  |  out: | ||||||
|  |  	return rc; | ||||||
|  |  out_ptype: | ||||||
|  | -	remove_proc_entry("ptype", net->proc_net); | ||||||
|  | +	if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		remove_proc_entry("ptype", net->proc_net); | ||||||
|  |  out_softnet: | ||||||
|  | -	remove_proc_entry("softnet_stat", net->proc_net); | ||||||
|  | +	if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		remove_proc_entry("softnet_stat", net->proc_net); | ||||||
|  |  out_dev: | ||||||
|  |  	remove_proc_entry("dev", net->proc_net); | ||||||
|  |  	goto out; | ||||||
|  | @@ -344,8 +348,10 @@ static void __net_exit dev_proc_net_exit | ||||||
|  |  { | ||||||
|  |  	wext_proc_exit(net); | ||||||
|  |   | ||||||
|  | -	remove_proc_entry("ptype", net->proc_net); | ||||||
|  | -	remove_proc_entry("softnet_stat", net->proc_net); | ||||||
|  | +	if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { | ||||||
|  | +		remove_proc_entry("ptype", net->proc_net); | ||||||
|  | +		remove_proc_entry("softnet_stat", net->proc_net); | ||||||
|  | +	} | ||||||
|  |  	remove_proc_entry("dev", net->proc_net); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | --- a/net/core/sock.c | ||||||
|  | +++ b/net/core/sock.c | ||||||
|  | @@ -3383,6 +3383,8 @@ static __net_initdata struct pernet_oper | ||||||
|  |   | ||||||
|  |  static int __init proto_init(void) | ||||||
|  |  { | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return 0; | ||||||
|  |  	return register_pernet_subsys(&proto_net_ops); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | --- a/net/ipv4/fib_trie.c | ||||||
|  | +++ b/net/ipv4/fib_trie.c | ||||||
|  | @@ -2731,10 +2731,12 @@ static const struct file_operations fib_ | ||||||
|  |   | ||||||
|  |  int __net_init fib_proc_init(struct net *net) | ||||||
|  |  { | ||||||
|  | -	if (!proc_create("fib_trie", S_IRUGO, net->proc_net, &fib_trie_fops)) | ||||||
|  | +	if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && | ||||||
|  | +		!proc_create("fib_trie", S_IRUGO, net->proc_net, &fib_trie_fops)) | ||||||
|  |  		goto out1; | ||||||
|  |   | ||||||
|  | -	if (!proc_create("fib_triestat", S_IRUGO, net->proc_net, | ||||||
|  | +	if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && | ||||||
|  | +		!proc_create("fib_triestat", S_IRUGO, net->proc_net, | ||||||
|  |  			 &fib_triestat_fops)) | ||||||
|  |  		goto out2; | ||||||
|  |   | ||||||
|  | @@ -2744,17 +2746,21 @@ int __net_init fib_proc_init(struct net | ||||||
|  |  	return 0; | ||||||
|  |   | ||||||
|  |  out3: | ||||||
|  | -	remove_proc_entry("fib_triestat", net->proc_net); | ||||||
|  | +	if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		remove_proc_entry("fib_triestat", net->proc_net); | ||||||
|  |  out2: | ||||||
|  | -	remove_proc_entry("fib_trie", net->proc_net); | ||||||
|  | +	if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		remove_proc_entry("fib_trie", net->proc_net); | ||||||
|  |  out1: | ||||||
|  |  	return -ENOMEM; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  void __net_exit fib_proc_exit(struct net *net) | ||||||
|  |  { | ||||||
|  | -	remove_proc_entry("fib_trie", net->proc_net); | ||||||
|  | -	remove_proc_entry("fib_triestat", net->proc_net); | ||||||
|  | +	if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { | ||||||
|  | +		remove_proc_entry("fib_trie", net->proc_net); | ||||||
|  | +		remove_proc_entry("fib_triestat", net->proc_net); | ||||||
|  | +	} | ||||||
|  |  	remove_proc_entry("route", net->proc_net); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | --- a/net/ipv4/proc.c | ||||||
|  | +++ b/net/ipv4/proc.c | ||||||
|  | @@ -557,6 +557,9 @@ static __net_initdata struct pernet_oper | ||||||
|  |   | ||||||
|  |  int __init ip_misc_proc_init(void) | ||||||
|  |  { | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  |  	return register_pernet_subsys(&ip_proc_ops); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | --- a/net/ipv4/route.c | ||||||
|  | +++ b/net/ipv4/route.c | ||||||
|  | @@ -424,6 +424,9 @@ static struct pernet_operations ip_rt_pr | ||||||
|  |   | ||||||
|  |  static int __init ip_rt_proc_init(void) | ||||||
|  |  { | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  |  	return register_pernet_subsys(&ip_rt_proc_ops); | ||||||
|  |  } | ||||||
|  |   | ||||||
							
								
								
									
										64
									
								
								target/linux/generic/hack-4.14/904-debloat_dma_buf.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								target/linux/generic/hack-4.14/904-debloat_dma_buf.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | |||||||
|  | From e3692cb2fcd5ba1244512a0f43b8118f65f1c375 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Sat, 8 Jul 2017 08:20:43 +0200 | ||||||
|  | Subject: debloat: dmabuf | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  drivers/base/Kconfig      |  2 +- | ||||||
|  |  drivers/dma-buf/Makefile  | 10 +++++++--- | ||||||
|  |  drivers/dma-buf/dma-buf.c |  4 +++- | ||||||
|  |  kernel/sched/core.c       |  1 + | ||||||
|  |  4 files changed, 12 insertions(+), 5 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/base/Kconfig | ||||||
|  | +++ b/drivers/base/Kconfig | ||||||
|  | @@ -243,7 +243,7 @@ config SOC_BUS | ||||||
|  |  source "drivers/base/regmap/Kconfig" | ||||||
|  |   | ||||||
|  |  config DMA_SHARED_BUFFER | ||||||
|  | -	bool | ||||||
|  | +	tristate | ||||||
|  |  	default n | ||||||
|  |  	select ANON_INODES | ||||||
|  |  	help | ||||||
|  | --- a/drivers/dma-buf/Makefile | ||||||
|  | +++ b/drivers/dma-buf/Makefile | ||||||
|  | @@ -1,3 +1,7 @@ | ||||||
|  | -obj-y := dma-buf.o dma-fence.o dma-fence-array.o reservation.o seqno-fence.o | ||||||
|  | -obj-$(CONFIG_SYNC_FILE)		+= sync_file.o | ||||||
|  | -obj-$(CONFIG_SW_SYNC)		+= sw_sync.o sync_debug.o | ||||||
|  | +obj-$(CONFIG_DMA_SHARED_BUFFER) := dma-shared-buffer.o | ||||||
|  | + | ||||||
|  | +dma-buf-objs-y := dma-buf.o dma-fence.o dma-fence-array.o reservation.o seqno-fence.o | ||||||
|  | +dma-buf-objs-$(CONFIG_SYNC_FILE)		+= sync_file.o | ||||||
|  | +dma-buf-objs-$(CONFIG_SW_SYNC)		+= sw_sync.o sync_debug.o | ||||||
|  | + | ||||||
|  | +dma-shared-buffer-objs :=  $(dma-buf-objs-y) | ||||||
|  | --- a/drivers/dma-buf/dma-buf.c | ||||||
|  | +++ b/drivers/dma-buf/dma-buf.c | ||||||
|  | @@ -34,6 +34,7 @@ | ||||||
|  |  #include <linux/poll.h> | ||||||
|  |  #include <linux/reservation.h> | ||||||
|  |  #include <linux/mm.h> | ||||||
|  | +#include <linux/module.h> | ||||||
|  |   | ||||||
|  |  #include <uapi/linux/dma-buf.h> | ||||||
|  |   | ||||||
|  | @@ -1205,4 +1206,5 @@ static void __exit dma_buf_deinit(void) | ||||||
|  |  { | ||||||
|  |  	dma_buf_uninit_debugfs(); | ||||||
|  |  } | ||||||
|  | -__exitcall(dma_buf_deinit); | ||||||
|  | +module_exit(dma_buf_deinit); | ||||||
|  | +MODULE_LICENSE("GPL"); | ||||||
|  | --- a/kernel/sched/core.c | ||||||
|  | +++ b/kernel/sched/core.c | ||||||
|  | @@ -2146,6 +2146,7 @@ int wake_up_state(struct task_struct *p, | ||||||
|  |  { | ||||||
|  |  	return try_to_wake_up(p, state, 0); | ||||||
|  |  } | ||||||
|  | +EXPORT_SYMBOL_GPL(wake_up_state); | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  |   * Perform scheduler related setup for a newly forked process p. | ||||||
							
								
								
									
										32
									
								
								target/linux/generic/hack-4.14/910-kobject_uevent.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								target/linux/generic/hack-4.14/910-kobject_uevent.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Sun, 16 Jul 2017 16:56:10 +0200 | ||||||
|  | Subject: lib: add uevent_next_seqnum() | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  include/linux/kobject.h |  5 +++++ | ||||||
|  |  lib/kobject_uevent.c    | 37 +++++++++++++++++++++++++++++++++++++ | ||||||
|  |  2 files changed, 42 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/lib/kobject_uevent.c | ||||||
|  | +++ b/lib/kobject_uevent.c | ||||||
|  | @@ -176,6 +176,18 @@ out: | ||||||
|  |  	return r; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +u64 uevent_next_seqnum(void) | ||||||
|  | +{ | ||||||
|  | +	u64 seq; | ||||||
|  | + | ||||||
|  | +	mutex_lock(&uevent_sock_mutex); | ||||||
|  | +	seq = ++uevent_seqnum; | ||||||
|  | +	mutex_unlock(&uevent_sock_mutex); | ||||||
|  | + | ||||||
|  | +	return seq; | ||||||
|  | +} | ||||||
|  | +EXPORT_SYMBOL_GPL(uevent_next_seqnum); | ||||||
|  | + | ||||||
|  |  /** | ||||||
|  |   * kobject_synth_uevent - send synthetic uevent with arguments | ||||||
|  |   * | ||||||
| @@ -0,0 +1,76 @@ | |||||||
|  | From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Sun, 16 Jul 2017 16:56:10 +0200 | ||||||
|  | Subject: lib: add uevent_next_seqnum() | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  include/linux/kobject.h |  5 +++++ | ||||||
|  |  lib/kobject_uevent.c    | 37 +++++++++++++++++++++++++++++++++++++ | ||||||
|  |  2 files changed, 42 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/include/linux/kobject.h | ||||||
|  | +++ b/include/linux/kobject.h | ||||||
|  | @@ -32,6 +32,8 @@ | ||||||
|  |  #define UEVENT_NUM_ENVP			32	/* number of env pointers */ | ||||||
|  |  #define UEVENT_BUFFER_SIZE		2048	/* buffer for the variables */ | ||||||
|  |   | ||||||
|  | +struct sk_buff; | ||||||
|  | + | ||||||
|  |  #ifdef CONFIG_UEVENT_HELPER | ||||||
|  |  /* path to the userspace helper executed on an event */ | ||||||
|  |  extern char uevent_helper[]; | ||||||
|  | @@ -224,4 +226,7 @@ int kobject_synth_uevent(struct kobject | ||||||
|  |  __printf(2, 3) | ||||||
|  |  int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...); | ||||||
|  |   | ||||||
|  | +int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, | ||||||
|  | +		     gfp_t allocation); | ||||||
|  | + | ||||||
|  |  #endif /* _KOBJECT_H_ */ | ||||||
|  | --- a/lib/kobject_uevent.c | ||||||
|  | +++ b/lib/kobject_uevent.c | ||||||
|  | @@ -599,6 +599,43 @@ int add_uevent_var(struct kobj_uevent_en | ||||||
|  |  EXPORT_SYMBOL_GPL(add_uevent_var); | ||||||
|  |   | ||||||
|  |  #if defined(CONFIG_NET) | ||||||
|  | +int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, | ||||||
|  | +		     gfp_t allocation) | ||||||
|  | +{ | ||||||
|  | +	struct uevent_sock *ue_sk; | ||||||
|  | +	int err = 0; | ||||||
|  | + | ||||||
|  | +	/* send netlink message */ | ||||||
|  | +	mutex_lock(&uevent_sock_mutex); | ||||||
|  | +	list_for_each_entry(ue_sk, &uevent_sock_list, list) { | ||||||
|  | +		struct sock *uevent_sock = ue_sk->sk; | ||||||
|  | +		struct sk_buff *skb2; | ||||||
|  | + | ||||||
|  | +		skb2 = skb_clone(skb, allocation); | ||||||
|  | +		if (!skb2) | ||||||
|  | +			break; | ||||||
|  | + | ||||||
|  | +		err = netlink_broadcast(uevent_sock, skb2, pid, group, | ||||||
|  | +					allocation); | ||||||
|  | +		if (err) | ||||||
|  | +			break; | ||||||
|  | +	} | ||||||
|  | +	mutex_unlock(&uevent_sock_mutex); | ||||||
|  | + | ||||||
|  | +	kfree_skb(skb); | ||||||
|  | +	return err; | ||||||
|  | +} | ||||||
|  | +#else | ||||||
|  | +int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group, | ||||||
|  | +		     gfp_t allocation) | ||||||
|  | +{ | ||||||
|  | +	kfree_skb(skb); | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | +#endif | ||||||
|  | +EXPORT_SYMBOL_GPL(broadcast_uevent); | ||||||
|  | + | ||||||
|  | +#if defined(CONFIG_NET) | ||||||
|  |  static int uevent_net_init(struct net *net) | ||||||
|  |  { | ||||||
|  |  	struct uevent_sock *ue_sk; | ||||||
| @@ -0,0 +1,40 @@ | |||||||
|  | From 5d301596fdc72f6cb672f72eb3c66e7cddefb103 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Sat, 8 Jul 2017 08:26:02 +0200 | ||||||
|  | Subject: initramfs: always create console node | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  scripts/gen_initramfs_list.sh | 14 ++++++++++++++ | ||||||
|  |  1 file changed, 14 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/scripts/gen_initramfs_list.sh | ||||||
|  | +++ b/scripts/gen_initramfs_list.sh | ||||||
|  | @@ -59,6 +59,18 @@ default_initramfs() { | ||||||
|  |  	EOF | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +list_openwrt_initramfs() { | ||||||
|  | +	: | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +openwrt_initramfs() { | ||||||
|  | +	# make sure that /dev/console exists | ||||||
|  | +	cat <<-EOF >> ${output} | ||||||
|  | +		dir /dev 0755 0 0 | ||||||
|  | +		nod /dev/console 0600 0 0 c 5 1 | ||||||
|  | +	EOF | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  filetype() { | ||||||
|  |  	local argv1="$1" | ||||||
|  |   | ||||||
|  | @@ -180,6 +192,8 @@ dir_filelist() { | ||||||
|  |  	if [  "$(echo "${dirlist}" | wc -l)" -gt 1 ]; then | ||||||
|  |  		${dep_list}print_mtime "$1" | ||||||
|  |   | ||||||
|  | +		${dep_list}openwrt_initramfs | ||||||
|  | + | ||||||
|  |  		echo "${dirlist}" | \ | ||||||
|  |  		while read x; do | ||||||
|  |  			${dep_list}parse ${x} | ||||||
							
								
								
									
										338
									
								
								target/linux/generic/hack-4.14/930-crashlog.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										338
									
								
								target/linux/generic/hack-4.14/930-crashlog.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,338 @@ | |||||||
|  | From 6b1ab74a9917012d0c559edc4ed299d9228ac89f Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Sat, 8 Jul 2017 08:26:47 +0200 | ||||||
|  | Subject: kernel: add the new 'crashlog' feature | ||||||
|  |  | ||||||
|  | this tries to store kernel oops/panic logs in a fixed location in RAM to | ||||||
|  | recover them available to user space using debugfs | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  include/linux/crashlog.h |  17 ++++ | ||||||
|  |  init/Kconfig             |   4 + | ||||||
|  |  kernel/Makefile          |   1 + | ||||||
|  |  kernel/crashlog.c        | 213 +++++++++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  kernel/module.c          |   3 + | ||||||
|  |  mm/bootmem.c             |   2 + | ||||||
|  |  mm/memblock.c            |   5 ++ | ||||||
|  |  7 files changed, 245 insertions(+) | ||||||
|  |  create mode 100644 include/linux/crashlog.h | ||||||
|  |  create mode 100644 kernel/crashlog.c | ||||||
|  |  | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/include/linux/crashlog.h | ||||||
|  | @@ -0,0 +1,17 @@ | ||||||
|  | +#ifndef __CRASHLOG_H | ||||||
|  | +#define __CRASHLOG_H | ||||||
|  | + | ||||||
|  | +#ifdef CONFIG_CRASHLOG | ||||||
|  | +void crashlog_init_bootmem(struct bootmem_data *bdata); | ||||||
|  | +void crashlog_init_memblock(phys_addr_t addr, phys_addr_t size); | ||||||
|  | +#else | ||||||
|  | +static inline void crashlog_init_bootmem(struct bootmem_data *bdata) | ||||||
|  | +{ | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static inline void crashlog_init_memblock(phys_addr_t addr, phys_addr_t size) | ||||||
|  | +{ | ||||||
|  | +} | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  | +#endif | ||||||
|  | --- a/init/Kconfig | ||||||
|  | +++ b/init/Kconfig | ||||||
|  | @@ -1009,6 +1009,10 @@ config RELAY | ||||||
|  |   | ||||||
|  |  	  If unsure, say N. | ||||||
|  |   | ||||||
|  | +config CRASHLOG | ||||||
|  | +	bool "Crash logging" | ||||||
|  | +	depends on (!NO_BOOTMEM || HAVE_MEMBLOCK) | ||||||
|  | + | ||||||
|  |  config BLK_DEV_INITRD | ||||||
|  |  	bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support" | ||||||
|  |  	depends on BROKEN || !FRV | ||||||
|  | --- a/kernel/Makefile | ||||||
|  | +++ b/kernel/Makefile | ||||||
|  | @@ -112,6 +112,7 @@ obj-$(CONFIG_CONTEXT_TRACKING) += contex | ||||||
|  |  obj-$(CONFIG_TORTURE_TEST) += torture.o | ||||||
|  |   | ||||||
|  |  obj-$(CONFIG_HAS_IOMEM) += memremap.o | ||||||
|  | +obj-$(CONFIG_CRASHLOG) += crashlog.o | ||||||
|  |   | ||||||
|  |  $(obj)/configs.o: $(obj)/config_data.h | ||||||
|  |   | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/kernel/crashlog.c | ||||||
|  | @@ -0,0 +1,213 @@ | ||||||
|  | +/* | ||||||
|  | + * Crash information logger | ||||||
|  | + * Copyright (C) 2010 Felix Fietkau <nbd@nbd.name> | ||||||
|  | + * | ||||||
|  | + * Based on ramoops.c | ||||||
|  | + *   Copyright (C) 2010 Marco Stornelli <marco.stornelli@gmail.com> | ||||||
|  | + * | ||||||
|  | + * This program is free software; you can redistribute it and/or | ||||||
|  | + * modify it under the terms of the GNU General Public License | ||||||
|  | + * version 2 as published by the Free Software Foundation. | ||||||
|  | + * | ||||||
|  | + * This program is distributed in the hope that it will be useful, but | ||||||
|  | + * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||||
|  | + * General Public License for more details. | ||||||
|  | + * | ||||||
|  | + * You should have received a copy of the GNU General Public License | ||||||
|  | + * along with this program; if not, write to the Free Software | ||||||
|  | + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||||||
|  | + * 02110-1301 USA | ||||||
|  | + * | ||||||
|  | + */ | ||||||
|  | + | ||||||
|  | +#include <linux/module.h> | ||||||
|  | +#include <linux/bootmem.h> | ||||||
|  | +#include <linux/memblock.h> | ||||||
|  | +#include <linux/debugfs.h> | ||||||
|  | +#include <linux/crashlog.h> | ||||||
|  | +#include <linux/kmsg_dump.h> | ||||||
|  | +#include <linux/module.h> | ||||||
|  | +#include <linux/pfn.h> | ||||||
|  | +#include <linux/vmalloc.h> | ||||||
|  | +#include <asm/io.h> | ||||||
|  | + | ||||||
|  | +#define CRASHLOG_PAGES	4 | ||||||
|  | +#define CRASHLOG_SIZE	(CRASHLOG_PAGES * PAGE_SIZE) | ||||||
|  | +#define CRASHLOG_MAGIC	0xa1eedead | ||||||
|  | + | ||||||
|  | +/* | ||||||
|  | + * Start the log at 1M before the end of RAM, as some boot loaders like | ||||||
|  | + * to use the end of the RAM for stack usage and other things | ||||||
|  | + * If this fails, fall back to using the last part. | ||||||
|  | + */ | ||||||
|  | +#define CRASHLOG_OFFSET	(1024 * 1024) | ||||||
|  | + | ||||||
|  | +struct crashlog_data { | ||||||
|  | +	u32 magic; | ||||||
|  | +	u32 len; | ||||||
|  | +	u8 data[]; | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +static struct debugfs_blob_wrapper crashlog_blob; | ||||||
|  | +static unsigned long crashlog_addr = 0; | ||||||
|  | +static struct crashlog_data *crashlog_buf; | ||||||
|  | +static struct kmsg_dumper dump; | ||||||
|  | +static bool first = true; | ||||||
|  | + | ||||||
|  | +extern struct list_head *crashlog_modules; | ||||||
|  | + | ||||||
|  | +static bool crashlog_set_addr(phys_addr_t addr, phys_addr_t size) | ||||||
|  | +{ | ||||||
|  | +	/* Limit to lower 64 MB to avoid highmem */ | ||||||
|  | +	phys_addr_t limit = 64 * 1024 * 1024; | ||||||
|  | + | ||||||
|  | +	if (crashlog_addr) | ||||||
|  | +		return false; | ||||||
|  | + | ||||||
|  | +	if (addr > limit) | ||||||
|  | +		return false; | ||||||
|  | + | ||||||
|  | +	if (addr + size > limit) | ||||||
|  | +		size = limit - addr; | ||||||
|  | + | ||||||
|  | +	crashlog_addr = addr; | ||||||
|  | + | ||||||
|  | +	if (addr + size > CRASHLOG_OFFSET) | ||||||
|  | +		crashlog_addr += size - CRASHLOG_OFFSET; | ||||||
|  | + | ||||||
|  | +	return true; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +#ifndef CONFIG_NO_BOOTMEM | ||||||
|  | +void __init crashlog_init_bootmem(bootmem_data_t *bdata) | ||||||
|  | +{ | ||||||
|  | +	phys_addr_t start, end; | ||||||
|  | + | ||||||
|  | +	start = PFN_PHYS(bdata->node_low_pfn); | ||||||
|  | +	end = PFN_PHYS(bdata->node_min_pfn); | ||||||
|  | +	if (!crashlog_set_addr(start, end - start)) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	if (reserve_bootmem(crashlog_addr, CRASHLOG_SIZE, BOOTMEM_EXCLUSIVE) < 0) { | ||||||
|  | +		printk("Crashlog failed to allocate RAM at address 0x%lx\n", | ||||||
|  | +		       crashlog_addr); | ||||||
|  | +		crashlog_addr = 0; | ||||||
|  | +	} | ||||||
|  | +} | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  | +#ifdef CONFIG_HAVE_MEMBLOCK | ||||||
|  | +void __init_memblock crashlog_init_memblock(phys_addr_t addr, phys_addr_t size) | ||||||
|  | +{ | ||||||
|  | +	if (!crashlog_set_addr(addr, size)) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	if (memblock_reserve(crashlog_addr, CRASHLOG_SIZE)) { | ||||||
|  | +		printk("Crashlog failed to allocate RAM at address 0x%lx\n", | ||||||
|  | +		       crashlog_addr); | ||||||
|  | +		crashlog_addr = 0; | ||||||
|  | +	} | ||||||
|  | +} | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  | +static void __init crashlog_copy(void) | ||||||
|  | +{ | ||||||
|  | +	if (crashlog_buf->magic != CRASHLOG_MAGIC) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	if (!crashlog_buf->len || crashlog_buf->len > | ||||||
|  | +	    CRASHLOG_SIZE - sizeof(*crashlog_buf)) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	crashlog_blob.size = crashlog_buf->len; | ||||||
|  | +	crashlog_blob.data = kmemdup(crashlog_buf->data, | ||||||
|  | +		crashlog_buf->len, GFP_KERNEL); | ||||||
|  | + | ||||||
|  | +	debugfs_create_blob("crashlog", 0700, NULL, &crashlog_blob); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int get_maxlen(void) | ||||||
|  | +{ | ||||||
|  | +	return CRASHLOG_SIZE - sizeof(*crashlog_buf) - crashlog_buf->len; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void crashlog_printf(const char *fmt, ...) | ||||||
|  | +{ | ||||||
|  | +	va_list args; | ||||||
|  | +	int len = get_maxlen(); | ||||||
|  | + | ||||||
|  | +	if (!len) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	va_start(args, fmt); | ||||||
|  | +	crashlog_buf->len += vscnprintf( | ||||||
|  | +		&crashlog_buf->data[crashlog_buf->len], | ||||||
|  | +		len, fmt, args); | ||||||
|  | +	va_end(args); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void crashlog_do_dump(struct kmsg_dumper *dumper, | ||||||
|  | +		enum kmsg_dump_reason reason) | ||||||
|  | +{ | ||||||
|  | +	struct timeval tv; | ||||||
|  | +	struct module *m; | ||||||
|  | +	char *buf; | ||||||
|  | +	size_t len; | ||||||
|  | + | ||||||
|  | +	if (!first) | ||||||
|  | +		crashlog_printf("\n===================================\n"); | ||||||
|  | + | ||||||
|  | +	do_gettimeofday(&tv); | ||||||
|  | +	crashlog_printf("Time: %lu.%lu\n", | ||||||
|  | +		(long)tv.tv_sec, (long)tv.tv_usec); | ||||||
|  | + | ||||||
|  | +	if (first) { | ||||||
|  | +		crashlog_printf("Modules:"); | ||||||
|  | +		list_for_each_entry(m, crashlog_modules, list) { | ||||||
|  | +			crashlog_printf("\t%s@%p+%x", m->name, | ||||||
|  | +			m->core_layout.base, m->core_layout.size, | ||||||
|  | +			m->init_layout.base, m->init_layout.size); | ||||||
|  | +		} | ||||||
|  | +		crashlog_printf("\n"); | ||||||
|  | +		first = false; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	buf = (char *)&crashlog_buf->data[crashlog_buf->len]; | ||||||
|  | + | ||||||
|  | +	kmsg_dump_get_buffer(dumper, true, buf, get_maxlen(), &len); | ||||||
|  | + | ||||||
|  | +	crashlog_buf->len += len; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | + | ||||||
|  | +int __init crashlog_init_fs(void) | ||||||
|  | +{ | ||||||
|  | +	struct page *pages[CRASHLOG_PAGES]; | ||||||
|  | +	pgprot_t prot; | ||||||
|  | +	int i; | ||||||
|  | + | ||||||
|  | +	if (!crashlog_addr) { | ||||||
|  | +		printk("No memory allocated for crashlog\n"); | ||||||
|  | +		return -ENOMEM; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	printk("Crashlog allocated RAM at address 0x%lx\n", (unsigned long) crashlog_addr); | ||||||
|  | +	for (i = 0; i < CRASHLOG_PAGES; i++) | ||||||
|  | +		pages[i] = pfn_to_page((crashlog_addr >> PAGE_SHIFT) + i); | ||||||
|  | + | ||||||
|  | +	prot = pgprot_writecombine(PAGE_KERNEL); | ||||||
|  | +	crashlog_buf = vmap(pages, CRASHLOG_PAGES, VM_MAP, prot); | ||||||
|  | + | ||||||
|  | +	crashlog_copy(); | ||||||
|  | + | ||||||
|  | +	crashlog_buf->magic = CRASHLOG_MAGIC; | ||||||
|  | +	crashlog_buf->len = 0; | ||||||
|  | + | ||||||
|  | +	dump.max_reason = KMSG_DUMP_OOPS; | ||||||
|  | +	dump.dump = crashlog_do_dump; | ||||||
|  | +	kmsg_dump_register(&dump); | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | +module_init(crashlog_init_fs); | ||||||
|  | --- a/kernel/module.c | ||||||
|  | +++ b/kernel/module.c | ||||||
|  | @@ -256,6 +256,9 @@ static void mod_update_bounds(struct mod | ||||||
|  |  #ifdef CONFIG_KGDB_KDB | ||||||
|  |  struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */ | ||||||
|  |  #endif /* CONFIG_KGDB_KDB */ | ||||||
|  | +#ifdef CONFIG_CRASHLOG | ||||||
|  | +struct list_head *crashlog_modules = &modules; | ||||||
|  | +#endif | ||||||
|  |   | ||||||
|  |  static void module_assert_mutex(void) | ||||||
|  |  { | ||||||
|  | --- a/mm/bootmem.c | ||||||
|  | +++ b/mm/bootmem.c | ||||||
|  | @@ -15,6 +15,7 @@ | ||||||
|  |  #include <linux/export.h> | ||||||
|  |  #include <linux/kmemleak.h> | ||||||
|  |  #include <linux/range.h> | ||||||
|  | +#include <linux/crashlog.h> | ||||||
|  |  #include <linux/bug.h> | ||||||
|  |  #include <linux/io.h> | ||||||
|  |  #include <linux/bootmem.h> | ||||||
|  | @@ -175,6 +176,7 @@ static unsigned long __init free_all_boo | ||||||
|  |  	if (!bdata->node_bootmem_map) | ||||||
|  |  		return 0; | ||||||
|  |   | ||||||
|  | +	crashlog_init_bootmem(bdata); | ||||||
|  |  	map = bdata->node_bootmem_map; | ||||||
|  |  	start = bdata->node_min_pfn; | ||||||
|  |  	end = bdata->node_low_pfn; | ||||||
|  | --- a/mm/memblock.c | ||||||
|  | +++ b/mm/memblock.c | ||||||
|  | @@ -19,6 +19,7 @@ | ||||||
|  |  #include <linux/debugfs.h> | ||||||
|  |  #include <linux/seq_file.h> | ||||||
|  |  #include <linux/memblock.h> | ||||||
|  | +#include <linux/crashlog.h> | ||||||
|  |   | ||||||
|  |  #include <asm/sections.h> | ||||||
|  |  #include <linux/io.h> | ||||||
|  | @@ -483,6 +484,8 @@ static void __init_memblock memblock_ins | ||||||
|  |  	memblock_set_region_node(rgn, nid); | ||||||
|  |  	type->cnt++; | ||||||
|  |  	type->total_size += size; | ||||||
|  | +	if (type == &memblock.memory) | ||||||
|  | +		crashlog_init_memblock(base, size); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /** | ||||||
|  | @@ -522,6 +525,8 @@ int __init_memblock memblock_add_range(s | ||||||
|  |  		type->regions[0].flags = flags; | ||||||
|  |  		memblock_set_region_node(&type->regions[0], nid); | ||||||
|  |  		type->total_size = size; | ||||||
|  | +		if (type == &memblock.memory) | ||||||
|  | +			crashlog_init_memblock(base, size); | ||||||
|  |  		return 0; | ||||||
|  |  	} | ||||||
|  |  repeat: | ||||||
| @@ -0,0 +1,30 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: MIPS: fix cache flushing for highmem pages | ||||||
|  |  | ||||||
|  | Most cache flush ops were no-op for highmem pages. This led to nasty | ||||||
|  | segfaults and (in the case of page_address(page) == NULL) kernel | ||||||
|  | crashes. | ||||||
|  |  | ||||||
|  | Fix this by always flushing highmem pages using kmap/kunmap_atomic | ||||||
|  | around the actual cache flush. This might be a bit inefficient, but at | ||||||
|  | least it's stable. | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/arch/mips/mm/cache.c | ||||||
|  | +++ b/arch/mips/mm/cache.c | ||||||
|  | @@ -116,6 +116,13 @@ void __flush_anon_page(struct page *page | ||||||
|  |  { | ||||||
|  |  	unsigned long addr = (unsigned long) page_address(page); | ||||||
|  |   | ||||||
|  | +	if (PageHighMem(page)) { | ||||||
|  | +		addr = (unsigned long)kmap_atomic(page); | ||||||
|  | +		flush_data_cache_page(addr); | ||||||
|  | +		__kunmap_atomic((void *)addr); | ||||||
|  | +		return; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	if (pages_do_alias(addr, vmaddr)) { | ||||||
|  |  		if (page_mapcount(page) && !Page_dcache_dirty(page)) { | ||||||
|  |  			void *kaddr; | ||||||
| @@ -0,0 +1,79 @@ | |||||||
|  | From: Florian Fainelli <florian@openwrt.org> | ||||||
|  | Subject: USB: EHCI: add ignore_oc flag to disable overcurrent checking | ||||||
|  |  | ||||||
|  | This patch adds an ignore_oc flag which can be set by EHCI controller | ||||||
|  | not supporting or wanting to disable overcurrent checking. The EHCI | ||||||
|  | platform data in include/linux/usb/ehci_pdriver.h is also augmented to | ||||||
|  | take advantage of this new flag. | ||||||
|  |  | ||||||
|  | Signed-off-by: Florian Fainelli <florian@openwrt.org> | ||||||
|  | --- | ||||||
|  |  drivers/usb/host/ehci-hcd.c      |    2 +- | ||||||
|  |  drivers/usb/host/ehci-hub.c      |    4 ++-- | ||||||
|  |  drivers/usb/host/ehci-platform.c |    1 + | ||||||
|  |  drivers/usb/host/ehci.h          |    1 + | ||||||
|  |  include/linux/usb/ehci_pdriver.h |    1 + | ||||||
|  |  5 files changed, 6 insertions(+), 3 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/usb/host/ehci-hcd.c | ||||||
|  | +++ b/drivers/usb/host/ehci-hcd.c | ||||||
|  | @@ -651,7 +651,7 @@ static int ehci_run (struct usb_hcd *hcd | ||||||
|  |  		"USB %x.%x started, EHCI %x.%02x%s\n", | ||||||
|  |  		((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), | ||||||
|  |  		temp >> 8, temp & 0xff, | ||||||
|  | -		ignore_oc ? ", overcurrent ignored" : ""); | ||||||
|  | +		(ignore_oc || ehci->ignore_oc) ? ", overcurrent ignored" : ""); | ||||||
|  |   | ||||||
|  |  	ehci_writel(ehci, INTR_MASK, | ||||||
|  |  		    &ehci->regs->intr_enable); /* Turn On Interrupts */ | ||||||
|  | --- a/drivers/usb/host/ehci-hub.c | ||||||
|  | +++ b/drivers/usb/host/ehci-hub.c | ||||||
|  | @@ -646,7 +646,7 @@ ehci_hub_status_data (struct usb_hcd *hc | ||||||
|  |  	 * always set, seem to clear PORT_OCC and PORT_CSC when writing to | ||||||
|  |  	 * PORT_POWER; that's surprising, but maybe within-spec. | ||||||
|  |  	 */ | ||||||
|  | -	if (!ignore_oc) | ||||||
|  | +	if (!ignore_oc && !ehci->ignore_oc) | ||||||
|  |  		mask = PORT_CSC | PORT_PEC | PORT_OCC; | ||||||
|  |  	else | ||||||
|  |  		mask = PORT_CSC | PORT_PEC; | ||||||
|  | @@ -1016,7 +1016,7 @@ int ehci_hub_control( | ||||||
|  |  		if (temp & PORT_PEC) | ||||||
|  |  			status |= USB_PORT_STAT_C_ENABLE << 16; | ||||||
|  |   | ||||||
|  | -		if ((temp & PORT_OCC) && !ignore_oc){ | ||||||
|  | +		if ((temp & PORT_OCC) && (!ignore_oc && !ehci->ignore_oc)){ | ||||||
|  |  			status |= USB_PORT_STAT_C_OVERCURRENT << 16; | ||||||
|  |   | ||||||
|  |  			/* | ||||||
|  | --- a/drivers/usb/host/ehci-platform.c | ||||||
|  | +++ b/drivers/usb/host/ehci-platform.c | ||||||
|  | @@ -263,6 +263,8 @@ static int ehci_platform_probe(struct pl | ||||||
|  |  		hcd->has_tt = 1; | ||||||
|  |  	if (pdata->reset_on_resume) | ||||||
|  |  		priv->reset_on_resume = true; | ||||||
|  | +	if (pdata->ignore_oc) | ||||||
|  | +		ehci->ignore_oc = 1; | ||||||
|  |   | ||||||
|  |  #ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO | ||||||
|  |  	if (ehci->big_endian_mmio) { | ||||||
|  | --- a/drivers/usb/host/ehci.h | ||||||
|  | +++ b/drivers/usb/host/ehci.h | ||||||
|  | @@ -231,6 +231,7 @@ struct ehci_hcd {			/* one per controlle | ||||||
|  |  	unsigned		frame_index_bug:1; /* MosChip (AKA NetMos) */ | ||||||
|  |  	unsigned		need_oc_pp_cycle:1; /* MPC834X port power */ | ||||||
|  |  	unsigned		imx28_write_fix:1; /* For Freescale i.MX28 */ | ||||||
|  | +	unsigned		ignore_oc:1; | ||||||
|  |   | ||||||
|  |  	/* required for usb32 quirk */ | ||||||
|  |  	#define OHCI_CTRL_HCFS          (3 << 6) | ||||||
|  | --- a/include/linux/usb/ehci_pdriver.h | ||||||
|  | +++ b/include/linux/usb/ehci_pdriver.h | ||||||
|  | @@ -49,6 +49,7 @@ struct usb_ehci_pdata { | ||||||
|  |  	unsigned	no_io_watchdog:1; | ||||||
|  |  	unsigned	reset_on_resume:1; | ||||||
|  |  	unsigned	dma_mask_64:1; | ||||||
|  | +	unsigned	ignore_oc:1; | ||||||
|  |   | ||||||
|  |  	/* Turn on all power and clocks */ | ||||||
|  |  	int (*power_on)(struct platform_device *pdev); | ||||||
| @@ -0,0 +1,82 @@ | |||||||
|  | From: Tobias Wolf <dev-NTEO@vplace.de> | ||||||
|  | Subject: mm: Fix alloc_node_mem_map with ARCH_PFN_OFFSET calculation | ||||||
|  |  | ||||||
|  | An rt288x (ralink) based router (Belkin F5D8235 v1) does not boot with any | ||||||
|  | kernel beyond version 4.3 resulting in: | ||||||
|  |  | ||||||
|  | BUG: Bad page state in process swapper  pfn:086ac | ||||||
|  |  | ||||||
|  | bisect resulted in: | ||||||
|  |  | ||||||
|  | a1c34a3bf00af2cede839879502e12dc68491ad5 is the first bad commit | ||||||
|  | commit a1c34a3bf00af2cede839879502e12dc68491ad5 | ||||||
|  | Author: Laura Abbott <laura@labbott.name> | ||||||
|  | Date:   Thu Nov 5 18:48:46 2015 -0800 | ||||||
|  |  | ||||||
|  |     mm: Don't offset memmap for flatmem | ||||||
|  |  | ||||||
|  |     Srinivas Kandagatla reported bad page messages when trying to remove the | ||||||
|  |     bottom 2MB on an ARM based IFC6410 board | ||||||
|  |  | ||||||
|  |       BUG: Bad page state in process swapper  pfn:fffa8 | ||||||
|  |       page:ef7fb500 count:0 mapcount:0 mapping:  (null) index:0x0 | ||||||
|  |       flags: 0x96640253(locked|error|dirty|active|arch_1|reclaim|mlocked) | ||||||
|  |       page dumped because: PAGE_FLAGS_CHECK_AT_FREE flag(s) set | ||||||
|  |       bad because of flags: | ||||||
|  |       flags: 0x200041(locked|active|mlocked) | ||||||
|  |       Modules linked in: | ||||||
|  |       CPU: 0 PID: 0 Comm: swapper Not tainted 3.19.0-rc3-00007-g412f9ba-dirty | ||||||
|  | #816 | ||||||
|  |       Hardware name: Qualcomm (Flattened Device Tree) | ||||||
|  |         unwind_backtrace | ||||||
|  |         show_stack | ||||||
|  |         dump_stack | ||||||
|  |         bad_page | ||||||
|  |         free_pages_prepare | ||||||
|  |         free_hot_cold_page | ||||||
|  |         __free_pages | ||||||
|  |         free_highmem_page | ||||||
|  |         mem_init | ||||||
|  |         start_kernel | ||||||
|  |       Disabling lock debugging due to kernel taint | ||||||
|  |     [...] | ||||||
|  | :040000 040000 2de013c372345fd471cd58f0553c9b38b0ef1cc4 | ||||||
|  | 0a8156f848733dfa21e16c196dfb6c0a76290709 M      mm | ||||||
|  |  | ||||||
|  | This fix for ARM does not account ARCH_PFN_OFFSET for mem_map as later used by | ||||||
|  | page_to_pfn anymore. | ||||||
|  |  | ||||||
|  | The following output was generated with two hacked in printk statements: | ||||||
|  |  | ||||||
|  | printk("before %p vs. %p or %p\n", mem_map, mem_map - offset, mem_map - | ||||||
|  | (pgdat->node_start_pfn - ARCH_PFN_OFFSET)); | ||||||
|  | 		if (page_to_pfn(mem_map) != pgdat->node_start_pfn) | ||||||
|  | 			mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET); | ||||||
|  | printk("after %p\n", mem_map); | ||||||
|  |  | ||||||
|  | Output: | ||||||
|  |  | ||||||
|  | [    0.000000] before 8861b280 vs. 8861b280 or 8851b280 | ||||||
|  | [    0.000000] after 8851b280 | ||||||
|  |  | ||||||
|  | As seen in the first line mem_map with subtraction of offset does not equal the | ||||||
|  | mem_map after subtraction of ARCH_PFN_OFFSET. | ||||||
|  |  | ||||||
|  | After adding the offset of ARCH_PFN_OFFSET as well to mem_map as the | ||||||
|  | previously calculated offset is zero for the named platform it is able to boot | ||||||
|  | 4.4 and 4.9-rc7 again. | ||||||
|  |  | ||||||
|  | Signed-off-by: Tobias Wolf <dev-NTEO@vplace.de> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/mm/page_alloc.c | ||||||
|  | +++ b/mm/page_alloc.c | ||||||
|  | @@ -6170,7 +6170,7 @@ static void __ref alloc_node_mem_map(str | ||||||
|  |  		mem_map = NODE_DATA(0)->node_mem_map; | ||||||
|  |  #if defined(CONFIG_HAVE_MEMBLOCK_NODE_MAP) || defined(CONFIG_FLATMEM) | ||||||
|  |  		if (page_to_pfn(mem_map) != pgdat->node_start_pfn) | ||||||
|  | -			mem_map -= offset; | ||||||
|  | +			mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET); | ||||||
|  |  #endif /* CONFIG_HAVE_MEMBLOCK_NODE_MAP */ | ||||||
|  |  	} | ||||||
|  |  #endif | ||||||
| @@ -0,0 +1,18 @@ | |||||||
|  | From: Giuseppe Lippolis <giu.lippolis@gmail.com> | ||||||
|  | Subject: Add the linux,spidev compatible in spidev Several device in ramips have this binding in the dts | ||||||
|  |  | ||||||
|  | Signed-off-by: Giuseppe Lippolis <giu.lippolis@gmail.com> | ||||||
|  | --- | ||||||
|  |  drivers/spi/spidev.c | 1 + | ||||||
|  |  1 file changed, 1 insertion(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/spi/spidev.c | ||||||
|  | +++ b/drivers/spi/spidev.c | ||||||
|  | @@ -669,6 +669,7 @@ static const struct of_device_id spidev_ | ||||||
|  |  	{ .compatible = "lineartechnology,ltc2488" }, | ||||||
|  |  	{ .compatible = "ge,achc" }, | ||||||
|  |  	{ .compatible = "semtech,sx1301" }, | ||||||
|  | +	{ .compatible = "siliconlabs,si3210" }, | ||||||
|  |  	{}, | ||||||
|  |  }; | ||||||
|  |  MODULE_DEVICE_TABLE(of, spidev_dt_ids); | ||||||
| @@ -0,0 +1,20 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: spi: use gpio_set_value_cansleep for setting chipselect GPIO | ||||||
|  |  | ||||||
|  | Sleeping is safe inside spi_transfer_one_message, and some GPIO chips | ||||||
|  | need to sleep for setting values | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/drivers/spi/spi.c | ||||||
|  | +++ b/drivers/spi/spi.c | ||||||
|  | @@ -729,7 +729,7 @@ static void spi_set_cs(struct spi_device | ||||||
|  |  		enable = !enable; | ||||||
|  |   | ||||||
|  |  	if (gpio_is_valid(spi->cs_gpio)) { | ||||||
|  | -		gpio_set_value(spi->cs_gpio, !enable); | ||||||
|  | +		gpio_set_value_cansleep(spi->cs_gpio, !enable); | ||||||
|  |  		/* Some SPI masters need both GPIO CS & slave_select */ | ||||||
|  |  		if ((spi->controller->flags & SPI_MASTER_GPIO_SS) && | ||||||
|  |  		    spi->controller->set_cs) | ||||||
| @@ -0,0 +1,62 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: jffs2: use .rename2 and add RENAME_WHITEOUT support | ||||||
|  |  | ||||||
|  | It is required for renames on overlayfs | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/fs/jffs2/dir.c | ||||||
|  | +++ b/fs/jffs2/dir.c | ||||||
|  | @@ -756,6 +756,24 @@ static int jffs2_mknod (struct inode *di | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static int jffs2_whiteout (struct inode *old_dir, struct dentry *old_dentry) | ||||||
|  | +{ | ||||||
|  | +	struct dentry *wh; | ||||||
|  | +	int err; | ||||||
|  | + | ||||||
|  | +	wh = d_alloc(old_dentry->d_parent, &old_dentry->d_name); | ||||||
|  | +	if (!wh) | ||||||
|  | +		return -ENOMEM; | ||||||
|  | + | ||||||
|  | +	err = jffs2_mknod(old_dir, wh, S_IFCHR | WHITEOUT_MODE, | ||||||
|  | +			  WHITEOUT_DEV); | ||||||
|  | +	if (err) | ||||||
|  | +		return err; | ||||||
|  | + | ||||||
|  | +	d_rehash(wh); | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry, | ||||||
|  |  			 struct inode *new_dir_i, struct dentry *new_dentry, | ||||||
|  |  			 unsigned int flags) | ||||||
|  | @@ -766,7 +784,7 @@ static int jffs2_rename (struct inode *o | ||||||
|  |  	uint8_t type; | ||||||
|  |  	uint32_t now; | ||||||
|  |   | ||||||
|  | -	if (flags & ~RENAME_NOREPLACE) | ||||||
|  | +	if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT)) | ||||||
|  |  		return -EINVAL; | ||||||
|  |   | ||||||
|  |  	/* The VFS will check for us and prevent trying to rename a | ||||||
|  | @@ -832,9 +850,14 @@ static int jffs2_rename (struct inode *o | ||||||
|  |  	if (d_is_dir(old_dentry) && !victim_f) | ||||||
|  |  		inc_nlink(new_dir_i); | ||||||
|  |   | ||||||
|  | -	/* Unlink the original */ | ||||||
|  | -	ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), | ||||||
|  | -			      old_dentry->d_name.name, old_dentry->d_name.len, NULL, now); | ||||||
|  | +	if (flags & RENAME_WHITEOUT) | ||||||
|  | +		/* Replace with whiteout */ | ||||||
|  | +		ret = jffs2_whiteout(old_dir_i, old_dentry); | ||||||
|  | +	else | ||||||
|  | +		/* Unlink the original */ | ||||||
|  | +		ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), | ||||||
|  | +				      old_dentry->d_name.name, | ||||||
|  | +				      old_dentry->d_name.len, NULL, now); | ||||||
|  |   | ||||||
|  |  	/* We don't touch inode->i_nlink */ | ||||||
|  |   | ||||||
| @@ -0,0 +1,73 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: jffs2: add RENAME_EXCHANGE support | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/fs/jffs2/dir.c | ||||||
|  | +++ b/fs/jffs2/dir.c | ||||||
|  | @@ -781,18 +781,31 @@ static int jffs2_rename (struct inode *o | ||||||
|  |  	int ret; | ||||||
|  |  	struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb); | ||||||
|  |  	struct jffs2_inode_info *victim_f = NULL; | ||||||
|  | +	struct inode *fst_inode = d_inode(old_dentry); | ||||||
|  | +	struct inode *snd_inode = d_inode(new_dentry); | ||||||
|  |  	uint8_t type; | ||||||
|  |  	uint32_t now; | ||||||
|  |   | ||||||
|  | -	if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT)) | ||||||
|  | +	if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT|RENAME_EXCHANGE)) | ||||||
|  |  		return -EINVAL; | ||||||
|  |   | ||||||
|  | +	if ((flags & RENAME_EXCHANGE) && (old_dir_i != new_dir_i)) { | ||||||
|  | +		if (S_ISDIR(fst_inode->i_mode) && !S_ISDIR(snd_inode->i_mode)) { | ||||||
|  | +			inc_nlink(new_dir_i); | ||||||
|  | +			drop_nlink(old_dir_i); | ||||||
|  | +		} | ||||||
|  | +		else if (!S_ISDIR(fst_inode->i_mode) && S_ISDIR(snd_inode->i_mode)) { | ||||||
|  | +			drop_nlink(new_dir_i); | ||||||
|  | +			inc_nlink(old_dir_i); | ||||||
|  | +		} | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	/* The VFS will check for us and prevent trying to rename a | ||||||
|  |  	 * file over a directory and vice versa, but if it's a directory, | ||||||
|  |  	 * the VFS can't check whether the victim is empty. The filesystem | ||||||
|  |  	 * needs to do that for itself. | ||||||
|  |  	 */ | ||||||
|  | -	if (d_really_is_positive(new_dentry)) { | ||||||
|  | +	if (d_really_is_positive(new_dentry) && !(flags & RENAME_EXCHANGE)) { | ||||||
|  |  		victim_f = JFFS2_INODE_INFO(d_inode(new_dentry)); | ||||||
|  |  		if (d_is_dir(new_dentry)) { | ||||||
|  |  			struct jffs2_full_dirent *fd; | ||||||
|  | @@ -827,7 +840,7 @@ static int jffs2_rename (struct inode *o | ||||||
|  |  	if (ret) | ||||||
|  |  		return ret; | ||||||
|  |   | ||||||
|  | -	if (victim_f) { | ||||||
|  | +	if (victim_f && !(flags & RENAME_EXCHANGE)) { | ||||||
|  |  		/* There was a victim. Kill it off nicely */ | ||||||
|  |  		if (d_is_dir(new_dentry)) | ||||||
|  |  			clear_nlink(d_inode(new_dentry)); | ||||||
|  | @@ -853,6 +866,12 @@ static int jffs2_rename (struct inode *o | ||||||
|  |  	if (flags & RENAME_WHITEOUT) | ||||||
|  |  		/* Replace with whiteout */ | ||||||
|  |  		ret = jffs2_whiteout(old_dir_i, old_dentry); | ||||||
|  | +	else if (flags & RENAME_EXCHANGE) | ||||||
|  | +		/* Replace the original */ | ||||||
|  | +		ret = jffs2_do_link(c, JFFS2_INODE_INFO(old_dir_i), | ||||||
|  | +				    d_inode(new_dentry)->i_ino, type, | ||||||
|  | +				    old_dentry->d_name.name, old_dentry->d_name.len, | ||||||
|  | +				    now); | ||||||
|  |  	else | ||||||
|  |  		/* Unlink the original */ | ||||||
|  |  		ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), | ||||||
|  | @@ -884,7 +903,7 @@ static int jffs2_rename (struct inode *o | ||||||
|  |  		return ret; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	if (d_is_dir(old_dentry)) | ||||||
|  | +	if (d_is_dir(old_dentry) && !(flags & RENAME_EXCHANGE)) | ||||||
|  |  		drop_nlink(old_dir_i); | ||||||
|  |   | ||||||
|  |  	new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now); | ||||||
| @@ -0,0 +1,43 @@ | |||||||
|  | From: Stephen Hemminger <stephen@networkplumber.org> | ||||||
|  | Subject: bridge: allow receiption on disabled port | ||||||
|  |  | ||||||
|  | When an ethernet device is enslaved to a bridge, and the bridge STP | ||||||
|  | detects loss of carrier (or operational state down), then normally | ||||||
|  | packet receiption is blocked. | ||||||
|  |  | ||||||
|  | This breaks control applications like WPA which maybe expecting to | ||||||
|  | receive packets to negotiate to bring link up. The bridge needs to | ||||||
|  | block forwarding packets from these disabled ports, but there is no | ||||||
|  | hard requirement to not allow local packet delivery. | ||||||
|  |  | ||||||
|  | Signed-off-by: Stephen Hemminger <stephen@networkplumber.org> | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  |  | ||||||
|  | --- a/net/bridge/br_input.c | ||||||
|  | +++ b/net/bridge/br_input.c | ||||||
|  | @@ -238,7 +238,8 @@ static int br_handle_local_finish(struct | ||||||
|  |  { | ||||||
|  |  	struct net_bridge_port *p = br_port_get_rcu(skb->dev); | ||||||
|  |   | ||||||
|  | -	__br_handle_local_finish(skb); | ||||||
|  | +	if (p->state != BR_STATE_DISABLED) | ||||||
|  | +		__br_handle_local_finish(skb); | ||||||
|  |   | ||||||
|  |  	BR_INPUT_SKB_CB(skb)->brdev = p->br->dev; | ||||||
|  |  	br_pass_frame_up(skb); | ||||||
|  | @@ -326,6 +327,15 @@ rx_handler_result_t br_handle_frame(stru | ||||||
|  |   | ||||||
|  |  forward: | ||||||
|  |  	switch (p->state) { | ||||||
|  | +	case BR_STATE_DISABLED: | ||||||
|  | +		if (ether_addr_equal(p->br->dev->dev_addr, dest)) | ||||||
|  | +			skb->pkt_type = PACKET_HOST; | ||||||
|  | + | ||||||
|  | +		NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, | ||||||
|  | +			dev_net(skb->dev), NULL, skb, skb->dev, NULL, | ||||||
|  | +			br_handle_local_finish); | ||||||
|  | +		break; | ||||||
|  | + | ||||||
|  |  	case BR_STATE_FORWARDING: | ||||||
|  |  		rhook = rcu_dereference(br_should_route_hook); | ||||||
|  |  		if (rhook) { | ||||||
| @@ -0,0 +1,161 @@ | |||||||
|  | From: Hauke Mehrtens <hauke@hauke-m.de> | ||||||
|  | Subject: mtd: part: add generic parsing of linux,part-probe | ||||||
|  |  | ||||||
|  | This moves the linux,part-probe device tree parsing code from | ||||||
|  | physmap_of.c to mtdpart.c. Now all drivers can use this feature by just | ||||||
|  | providing a reference to their device tree node in struct | ||||||
|  | mtd_part_parser_data. | ||||||
|  |  | ||||||
|  | Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> | ||||||
|  | --- | ||||||
|  |  Documentation/devicetree/bindings/mtd/nand.txt | 16 +++++++++ | ||||||
|  |  drivers/mtd/maps/physmap_of.c                  | 46 +------------------------- | ||||||
|  |  drivers/mtd/mtdpart.c                          | 45 +++++++++++++++++++++++++ | ||||||
|  |  3 files changed, 62 insertions(+), 45 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/Documentation/devicetree/bindings/mtd/nand.txt | ||||||
|  | +++ b/Documentation/devicetree/bindings/mtd/nand.txt | ||||||
|  | @@ -44,6 +44,22 @@ Optional NAND chip properties: | ||||||
|  |  		     used by the upper layers, and you want to make your NAND | ||||||
|  |  		     as reliable as possible. | ||||||
|  |   | ||||||
|  | +- linux,part-probe: list of name as strings of the partition parser | ||||||
|  | +		    which should be used to parse the partition table. | ||||||
|  | +		    They will be tried in the specified ordering and | ||||||
|  | +		    the next one will be used if the previous one | ||||||
|  | +		    failed. | ||||||
|  | + | ||||||
|  | +		    Example: linux,part-probe = "cmdlinepart", "ofpart"; | ||||||
|  | + | ||||||
|  | +		    This is also the default value, which will be used | ||||||
|  | +		    if this attribute is not specified. It could be | ||||||
|  | +		    that the flash driver in use overwrote the default | ||||||
|  | +		    value and uses some other default. | ||||||
|  | + | ||||||
|  | +		    Possible values are: bcm47xxpart, afs, ar7part, | ||||||
|  | +		    ofoldpart, ofpart, bcm63xxpart, RedBoot, cmdlinepart | ||||||
|  | + | ||||||
|  |  The ECC strength and ECC step size properties define the correction capability | ||||||
|  |  of a controller. Together, they say a controller can correct "{strength} bit | ||||||
|  |  errors per {size} bytes". | ||||||
|  | --- a/drivers/mtd/maps/physmap_of_core.c | ||||||
|  | +++ b/drivers/mtd/maps/physmap_of_core.c | ||||||
|  | @@ -114,37 +114,9 @@ static struct mtd_info *obsolete_probe(s | ||||||
|  |  static const char * const part_probe_types_def[] = { | ||||||
|  |  	"cmdlinepart", "RedBoot", "ofpart", "ofoldpart", NULL }; | ||||||
|  |   | ||||||
|  | -static const char * const *of_get_probes(struct device_node *dp) | ||||||
|  | -{ | ||||||
|  | -	const char **res; | ||||||
|  | -	int count; | ||||||
|  | - | ||||||
|  | -	count = of_property_count_strings(dp, "linux,part-probe"); | ||||||
|  | -	if (count < 0) | ||||||
|  | -		return part_probe_types_def; | ||||||
|  | - | ||||||
|  | -	res = kzalloc((count + 1) * sizeof(*res), GFP_KERNEL); | ||||||
|  | -	if (!res) | ||||||
|  | -		return NULL; | ||||||
|  | - | ||||||
|  | -	count = of_property_read_string_array(dp, "linux,part-probe", res, | ||||||
|  | -					      count); | ||||||
|  | -	if (count < 0) | ||||||
|  | -		return NULL; | ||||||
|  | - | ||||||
|  | -	return res; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static void of_free_probes(const char * const *probes) | ||||||
|  | -{ | ||||||
|  | -	if (probes != part_probe_types_def) | ||||||
|  | -		kfree(probes); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  |  static const struct of_device_id of_flash_match[]; | ||||||
|  |  static int of_flash_probe(struct platform_device *dev) | ||||||
|  |  { | ||||||
|  | -	const char * const *part_probe_types; | ||||||
|  |  	const struct of_device_id *match; | ||||||
|  |  	struct device_node *dp = dev->dev.of_node; | ||||||
|  |  	struct resource res; | ||||||
|  | @@ -310,14 +282,8 @@ static int of_flash_probe(struct platfor | ||||||
|  |   | ||||||
|  |  	info->cmtd->dev.parent = &dev->dev; | ||||||
|  |  	mtd_set_of_node(info->cmtd, dp); | ||||||
|  | -	part_probe_types = of_get_probes(dp); | ||||||
|  | -	if (!part_probe_types) { | ||||||
|  | -		err = -ENOMEM; | ||||||
|  | -		goto err_out; | ||||||
|  | -	} | ||||||
|  | -	mtd_device_parse_register(info->cmtd, part_probe_types, NULL, | ||||||
|  | +	mtd_device_parse_register(info->cmtd, part_probe_types_def, NULL, | ||||||
|  |  			NULL, 0); | ||||||
|  | -	of_free_probes(part_probe_types); | ||||||
|  |   | ||||||
|  |  	kfree(mtd_list); | ||||||
|  |   | ||||||
|  | --- a/drivers/mtd/mtdpart.c | ||||||
|  | +++ b/drivers/mtd/mtdpart.c | ||||||
|  | @@ -29,6 +29,7 @@ | ||||||
|  |  #include <linux/kmod.h> | ||||||
|  |  #include <linux/mtd/mtd.h> | ||||||
|  |  #include <linux/mtd/partitions.h> | ||||||
|  | +#include <linux/of.h> | ||||||
|  |  #include <linux/err.h> | ||||||
|  |   | ||||||
|  |  #include "mtdcore.h" | ||||||
|  | @@ -863,6 +864,32 @@ void deregister_mtd_parser(struct mtd_pa | ||||||
|  |  EXPORT_SYMBOL_GPL(deregister_mtd_parser); | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  | + * Parses the linux,part-probe device tree property. | ||||||
|  | + * When a non null value is returned it has to be freed with kfree() by | ||||||
|  | + * the caller. | ||||||
|  | + */ | ||||||
|  | +static const char * const *of_get_probes(struct device_node *dp) | ||||||
|  | +{ | ||||||
|  | +	const char **res; | ||||||
|  | +	int count; | ||||||
|  | + | ||||||
|  | +	count = of_property_count_strings(dp, "linux,part-probe"); | ||||||
|  | +	if (count < 0) | ||||||
|  | +		return NULL; | ||||||
|  | + | ||||||
|  | +	res = kzalloc((count + 1) * sizeof(*res), GFP_KERNEL); | ||||||
|  | +	if (!res) | ||||||
|  | +		return NULL; | ||||||
|  | + | ||||||
|  | +	count = of_property_read_string_array(dp, "linux,part-probe", res, | ||||||
|  | +					      count); | ||||||
|  | +	if (count < 0) | ||||||
|  | +		return NULL; | ||||||
|  | + | ||||||
|  | +	return res; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +/* | ||||||
|  |   * Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you | ||||||
|  |   * are changing this array! | ||||||
|  |   */ | ||||||
|  | @@ -920,6 +947,13 @@ int parse_mtd_partitions(struct mtd_info | ||||||
|  |  { | ||||||
|  |  	struct mtd_part_parser *parser; | ||||||
|  |  	int ret, err = 0; | ||||||
|  | +	const char *const *types_of = NULL; | ||||||
|  | + | ||||||
|  | +	if (mtd_get_of_node(master)) { | ||||||
|  | +		types_of = of_get_probes(mtd_get_of_node(master)); | ||||||
|  | +		if (types_of != NULL) | ||||||
|  | +			types = types_of; | ||||||
|  | +	} | ||||||
|  |   | ||||||
|  |  	if (!types) | ||||||
|  |  		types = default_mtd_part_types; | ||||||
|  | @@ -945,6 +979,7 @@ int parse_mtd_partitions(struct mtd_info | ||||||
|  |  		if (ret < 0 && !err) | ||||||
|  |  			err = ret; | ||||||
|  |  	} | ||||||
|  | +	kfree(types_of); | ||||||
|  |  	return err; | ||||||
|  |  } | ||||||
|  |   | ||||||
| @@ -0,0 +1,70 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: net: phy: at803x: add support for AT8032 | ||||||
|  |  | ||||||
|  | Like AT8030, this PHY needs the GPIO reset workaround | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/drivers/net/phy/at803x.c | ||||||
|  | +++ b/drivers/net/phy/at803x.c | ||||||
|  | @@ -62,6 +62,7 @@ | ||||||
|  |   | ||||||
|  |  #define ATH8030_PHY_ID 0x004dd076 | ||||||
|  |  #define ATH8031_PHY_ID 0x004dd074 | ||||||
|  | +#define ATH8032_PHY_ID 0x004dd023 | ||||||
|  |  #define ATH8035_PHY_ID 0x004dd072 | ||||||
|  |  #define AT803X_PHY_ID_MASK			0xffffffef | ||||||
|  |   | ||||||
|  | @@ -260,7 +261,8 @@ static int at803x_probe(struct phy_devic | ||||||
|  |  	if (!priv) | ||||||
|  |  		return -ENOMEM; | ||||||
|  |   | ||||||
|  | -	if (phydev->drv->phy_id != ATH8030_PHY_ID) | ||||||
|  | +	if (phydev->drv->phy_id != ATH8030_PHY_ID && | ||||||
|  | +	    phydev->drv->phy_id != ATH8032_PHY_ID) | ||||||
|  |  		goto does_not_require_reset_workaround; | ||||||
|  |   | ||||||
|  |  	gpiod_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); | ||||||
|  | @@ -336,7 +338,7 @@ static void at803x_link_change_notify(st | ||||||
|  |  	struct at803x_priv *priv = phydev->priv; | ||||||
|  |   | ||||||
|  |  	/* | ||||||
|  | -	 * Conduct a hardware reset for AT8030 every time a link loss is | ||||||
|  | +	 * Conduct a hardware reset for AT8030/2 every time a link loss is | ||||||
|  |  	 * signalled. This is necessary to circumvent a hardware bug that | ||||||
|  |  	 * occurs when the cable is unplugged while TX packets are pending | ||||||
|  |  	 * in the FIFO. In such cases, the FIFO enters an error mode it | ||||||
|  | @@ -448,6 +450,24 @@ static struct phy_driver at803x_driver[] | ||||||
|  |  	.aneg_done		= at803x_aneg_done, | ||||||
|  |  	.ack_interrupt		= &at803x_ack_interrupt, | ||||||
|  |  	.config_intr		= &at803x_config_intr, | ||||||
|  | +}, { | ||||||
|  | +	/* ATHEROS 8032 */ | ||||||
|  | +	.phy_id			= ATH8032_PHY_ID, | ||||||
|  | +	.name			= "Atheros 8032 ethernet", | ||||||
|  | +	.phy_id_mask		= 0xffffffef, | ||||||
|  | +	.probe			= at803x_probe, | ||||||
|  | +	.config_init		= at803x_config_init, | ||||||
|  | +	.link_change_notify	= at803x_link_change_notify, | ||||||
|  | +	.set_wol		= at803x_set_wol, | ||||||
|  | +	.get_wol		= at803x_get_wol, | ||||||
|  | +	.suspend		= at803x_suspend, | ||||||
|  | +	.resume			= at803x_resume, | ||||||
|  | +	.features		= PHY_BASIC_FEATURES, | ||||||
|  | +	.flags			= PHY_HAS_INTERRUPT, | ||||||
|  | +	.config_aneg		= genphy_config_aneg, | ||||||
|  | +	.read_status		= genphy_read_status, | ||||||
|  | +	.ack_interrupt		= at803x_ack_interrupt, | ||||||
|  | +	.config_intr		= at803x_config_intr, | ||||||
|  |  } }; | ||||||
|  |   | ||||||
|  |  module_phy_driver(at803x_driver); | ||||||
|  | @@ -455,6 +475,7 @@ module_phy_driver(at803x_driver); | ||||||
|  |  static struct mdio_device_id __maybe_unused atheros_tbl[] = { | ||||||
|  |  	{ ATH8030_PHY_ID, AT803X_PHY_ID_MASK }, | ||||||
|  |  	{ ATH8031_PHY_ID, AT803X_PHY_ID_MASK }, | ||||||
|  | +	{ ATH8032_PHY_ID, AT803X_PHY_ID_MASK }, | ||||||
|  |  	{ ATH8035_PHY_ID, AT803X_PHY_ID_MASK }, | ||||||
|  |  	{ } | ||||||
|  |  }; | ||||||
| @@ -0,0 +1,43 @@ | |||||||
|  | From patchwork Fri Jul 21 18:36:24 2017 | ||||||
|  | Content-Type: text/plain; charset="utf-8" | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Transfer-Encoding: 7bit | ||||||
|  | Subject: [2/5] e1000e: Fix wrong comment related to link detection | ||||||
|  | From: Benjamin Poirier <bpoirier@suse.com> | ||||||
|  | X-Patchwork-Id: 9857489 | ||||||
|  | Message-Id: <20170721183627.13373-2-bpoirier@suse.com> | ||||||
|  | To: Jeff Kirsher <jeffrey.t.kirsher@intel.com> | ||||||
|  | Cc: Lennart Sorensen <lsorense@csclub.uwaterloo.ca>, | ||||||
|  |  intel-wired-lan@lists.osuosl.org, netdev@vger.kernel.org, | ||||||
|  |  linux-kernel@vger.kernel.org | ||||||
|  | Date: Fri, 21 Jul 2017 11:36:24 -0700 | ||||||
|  |  | ||||||
|  | Reading e1000e_check_for_copper_link() shows that get_link_status is set to | ||||||
|  | false after link has been detected. Therefore, it stays TRUE until then. | ||||||
|  |  | ||||||
|  | Signed-off-by: Benjamin Poirier <bpoirier@suse.com> | ||||||
|  | Tested-by: Aaron Brown <aaron.f.brown@intel.com> | ||||||
|  | --- | ||||||
|  |  drivers/net/ethernet/intel/e1000e/netdev.c | 4 ++-- | ||||||
|  |  1 file changed, 2 insertions(+), 2 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/ethernet/intel/e1000e/netdev.c | ||||||
|  | +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | ||||||
|  | @@ -5096,7 +5096,7 @@ static bool e1000e_has_link(struct e1000 | ||||||
|  |   | ||||||
|  |  	/* get_link_status is set on LSC (link status) interrupt or | ||||||
|  |  	 * Rx sequence error interrupt.  get_link_status will stay | ||||||
|  | -	 * false until the check_for_link establishes link | ||||||
|  | +	 * true until the check_for_link establishes link | ||||||
|  |  	 * for copper adapters ONLY | ||||||
|  |  	 */ | ||||||
|  |  	switch (hw->phy.media_type) { | ||||||
|  | @@ -5114,7 +5114,7 @@ static bool e1000e_has_link(struct e1000 | ||||||
|  |  		break; | ||||||
|  |  	case e1000_media_type_internal_serdes: | ||||||
|  |  		ret_val = hw->mac.ops.check_for_link(hw); | ||||||
|  | -		link_active = adapter->hw.mac.serdes_has_link; | ||||||
|  | +		link_active = hw->mac.serdes_has_link; | ||||||
|  |  		break; | ||||||
|  |  	default: | ||||||
|  |  	case e1000_media_type_unknown: | ||||||
| @@ -0,0 +1,32 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: Upgrade to Linux 2.6.19 | ||||||
|  |  | ||||||
|  | - Includes large parts of the patch from #1021 by dpalffy | ||||||
|  | - Includes RB532 NAND driver changes by n0-1 | ||||||
|  |  | ||||||
|  | [john@phrozen.org: feix will add this to his upstream queue] | ||||||
|  |  | ||||||
|  | lede-commit: bff468813f78f81e36ebb2a3f4354de7365e640f | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  Makefile | 6 +++--- | ||||||
|  |  1 file changed, 3 insertions(+), 3 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/Makefile | ||||||
|  | +++ b/Makefile | ||||||
|  | @@ -637,12 +637,12 @@ KBUILD_CFLAGS	+= $(call cc-disable-warni | ||||||
|  |   | ||||||
|  |  ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE | ||||||
|  |  KBUILD_CFLAGS	+= $(call cc-option,-Oz,-Os) | ||||||
|  | -KBUILD_CFLAGS	+= $(call cc-disable-warning,maybe-uninitialized,) | ||||||
|  | +KBUILD_CFLAGS	+= $(call cc-disable-warning,maybe-uninitialized,) $(EXTRA_OPTIMIZATION) | ||||||
|  |  else | ||||||
|  |  ifdef CONFIG_PROFILE_ALL_BRANCHES | ||||||
|  | -KBUILD_CFLAGS	+= -O2 $(call cc-disable-warning,maybe-uninitialized,) | ||||||
|  | +KBUILD_CFLAGS	+= -O2 $(call cc-disable-warning,maybe-uninitialized,) $(EXTRA_OPTIMIZATION) | ||||||
|  |  else | ||||||
|  | -KBUILD_CFLAGS   += -O2 | ||||||
|  | +KBUILD_CFLAGS   += -O2 -fno-reorder-blocks -fno-tree-ch $(EXTRA_OPTIMIZATION) | ||||||
|  |  endif | ||||||
|  |  endif | ||||||
|  |   | ||||||
| @@ -0,0 +1,119 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: kernel: add a config option for keeping the kallsyms table uncompressed, saving ~9kb kernel size after lzma on ar71xx | ||||||
|  |  | ||||||
|  | [john@phrozen.org: added to my upstream queue 30.12.2016] | ||||||
|  | lede-commit: e0e3509b5ce2ccf93d4d67ea907613f5f7ec2eed | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  init/Kconfig            | 11 +++++++++++ | ||||||
|  |  kernel/kallsyms.c       |  8 ++++++++ | ||||||
|  |  scripts/kallsyms.c      | 12 ++++++++++++ | ||||||
|  |  scripts/link-vmlinux.sh |  4 ++++ | ||||||
|  |  4 files changed, 35 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/init/Kconfig | ||||||
|  | +++ b/init/Kconfig | ||||||
|  | @@ -1081,6 +1081,17 @@ config SYSCTL_ARCH_UNALIGN_ALLOW | ||||||
|  |  	  the unaligned access emulation. | ||||||
|  |  	  see arch/parisc/kernel/unaligned.c for reference | ||||||
|  |   | ||||||
|  | +config KALLSYMS_UNCOMPRESSED | ||||||
|  | +	bool "Keep kallsyms uncompressed" | ||||||
|  | +	depends on KALLSYMS | ||||||
|  | +	help | ||||||
|  | +		Normally kallsyms contains compressed symbols (using a token table), | ||||||
|  | +		reducing the uncompressed kernel image size. Keeping the symbol table | ||||||
|  | +		uncompressed significantly improves the size of this part in compressed | ||||||
|  | +		kernel images. | ||||||
|  | + | ||||||
|  | +		Say N unless you need compressed kernel images to be small. | ||||||
|  | + | ||||||
|  |  config HAVE_PCSPKR_PLATFORM | ||||||
|  |  	bool | ||||||
|  |   | ||||||
|  | --- a/kernel/kallsyms.c | ||||||
|  | +++ b/kernel/kallsyms.c | ||||||
|  | @@ -108,6 +108,11 @@ static unsigned int kallsyms_expand_symb | ||||||
|  |  	 * For every byte on the compressed symbol data, copy the table | ||||||
|  |  	 * entry for that byte. | ||||||
|  |  	 */ | ||||||
|  | +#ifdef CONFIG_KALLSYMS_UNCOMPRESSED | ||||||
|  | +	memcpy(result, data + 1, len - 1); | ||||||
|  | +	result += len - 1; | ||||||
|  | +	len = 0; | ||||||
|  | +#endif | ||||||
|  |  	while (len) { | ||||||
|  |  		tptr = &kallsyms_token_table[kallsyms_token_index[*data]]; | ||||||
|  |  		data++; | ||||||
|  | @@ -140,6 +145,9 @@ tail: | ||||||
|  |   */ | ||||||
|  |  static char kallsyms_get_symbol_type(unsigned int off) | ||||||
|  |  { | ||||||
|  | +#ifdef CONFIG_KALLSYMS_UNCOMPRESSED | ||||||
|  | +	return kallsyms_names[off + 1]; | ||||||
|  | +#endif | ||||||
|  |  	/* | ||||||
|  |  	 * Get just the first code, look it up in the token table, | ||||||
|  |  	 * and return the first char from this token. | ||||||
|  | --- a/scripts/kallsyms.c | ||||||
|  | +++ b/scripts/kallsyms.c | ||||||
|  | @@ -61,6 +61,7 @@ static struct addr_range percpu_range = | ||||||
|  |  static struct sym_entry *table; | ||||||
|  |  static unsigned int table_size, table_cnt; | ||||||
|  |  static int all_symbols = 0; | ||||||
|  | +static int uncompressed = 0; | ||||||
|  |  static int absolute_percpu = 0; | ||||||
|  |  static char symbol_prefix_char = '\0'; | ||||||
|  |  static int base_relative = 0; | ||||||
|  | @@ -457,6 +458,9 @@ static void write_src(void) | ||||||
|  |   | ||||||
|  |  	free(markers); | ||||||
|  |   | ||||||
|  | +	if (uncompressed) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  |  	output_label("kallsyms_token_table"); | ||||||
|  |  	off = 0; | ||||||
|  |  	for (i = 0; i < 256; i++) { | ||||||
|  | @@ -515,6 +519,9 @@ static void *find_token(unsigned char *s | ||||||
|  |  { | ||||||
|  |  	int i; | ||||||
|  |   | ||||||
|  | +	if (uncompressed) | ||||||
|  | +		return NULL; | ||||||
|  | + | ||||||
|  |  	for (i = 0; i < len - 1; i++) { | ||||||
|  |  		if (str[i] == token[0] && str[i+1] == token[1]) | ||||||
|  |  			return &str[i]; | ||||||
|  | @@ -587,6 +594,9 @@ static void optimize_result(void) | ||||||
|  |  { | ||||||
|  |  	int i, best; | ||||||
|  |   | ||||||
|  | +	if (uncompressed) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  |  	/* using the '\0' symbol last allows compress_symbols to use standard | ||||||
|  |  	 * fast string functions */ | ||||||
|  |  	for (i = 255; i >= 0; i--) { | ||||||
|  | @@ -775,6 +785,8 @@ int main(int argc, char **argv) | ||||||
|  |  				symbol_prefix_char = *p; | ||||||
|  |  			} else if (strcmp(argv[i], "--base-relative") == 0) | ||||||
|  |  				base_relative = 1; | ||||||
|  | +			else if (strcmp(argv[i], "--uncompressed") == 0) | ||||||
|  | +				uncompressed = 1; | ||||||
|  |  			else | ||||||
|  |  				usage(); | ||||||
|  |  		} | ||||||
|  | --- a/scripts/link-vmlinux.sh | ||||||
|  | +++ b/scripts/link-vmlinux.sh | ||||||
|  | @@ -164,6 +164,10 @@ kallsyms() | ||||||
|  |  		kallsymopt="${kallsymopt} --base-relative" | ||||||
|  |  	fi | ||||||
|  |   | ||||||
|  | +	if [ -n "${CONFIG_KALLSYMS_UNCOMPRESSED}" ]; then | ||||||
|  | +		kallsymopt="${kallsymopt} --uncompressed" | ||||||
|  | +	fi | ||||||
|  | + | ||||||
|  |  	local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL}               \ | ||||||
|  |  		      ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}" | ||||||
|  |   | ||||||
| @@ -0,0 +1,45 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: kernel: when KALLSYMS is disabled, print module address + size for matching backtrace entries | ||||||
|  |  | ||||||
|  | [john@phrozen.org: felix will add this to his upstream queue] | ||||||
|  |  | ||||||
|  | lede-commit 53827cdc824556cda910b23ce5030c363b8f1461 | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  lib/vsprintf.c | 15 +++++++++++---- | ||||||
|  |  1 file changed, 11 insertions(+), 4 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/lib/vsprintf.c | ||||||
|  | +++ b/lib/vsprintf.c | ||||||
|  | @@ -670,8 +670,10 @@ char *symbol_string(char *buf, char *end | ||||||
|  |  		    struct printf_spec spec, const char *fmt) | ||||||
|  |  { | ||||||
|  |  	unsigned long value; | ||||||
|  | -#ifdef CONFIG_KALLSYMS | ||||||
|  |  	char sym[KSYM_SYMBOL_LEN]; | ||||||
|  | +#ifndef CONFIG_KALLSYMS | ||||||
|  | +	struct module *mod; | ||||||
|  | +	int len; | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  |  	if (fmt[1] == 'R') | ||||||
|  | @@ -685,11 +687,16 @@ char *symbol_string(char *buf, char *end | ||||||
|  |  		sprint_symbol(sym, value); | ||||||
|  |  	else | ||||||
|  |  		sprint_symbol_no_offset(sym, value); | ||||||
|  | - | ||||||
|  | -	return string(buf, end, sym, spec); | ||||||
|  |  #else | ||||||
|  | -	return special_hex_number(buf, end, value, sizeof(void *)); | ||||||
|  | +	len = snprintf(sym, sizeof(sym), "0x%lx", value); | ||||||
|  | + | ||||||
|  | +	mod = __module_address(value); | ||||||
|  | +	if (mod) | ||||||
|  | +		snprintf(sym + len, sizeof(sym) - len, " [%s@%p+0x%x]", | ||||||
|  | +			 mod->name, mod->core_layout.base, | ||||||
|  | +			 mod->core_layout.size); | ||||||
|  |  #endif | ||||||
|  | +	return string(buf, end, sym, spec); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static noinline_for_stack | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: kernel: disable MIPS VDSO by default until the cache issues have been resolved | ||||||
|  |  | ||||||
|  | lede-commit: 1185e645a773c86aa88cf04d0e2911dc62eb43f5 | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  arch/mips/vdso/Makefile | 4 ++-- | ||||||
|  |  1 file changed, 2 insertions(+), 2 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/arch/mips/vdso/Makefile | ||||||
|  | +++ b/arch/mips/vdso/Makefile | ||||||
|  | @@ -30,9 +30,9 @@ aflags-vdso := $(ccflags-vdso) \ | ||||||
|  |  ifndef CONFIG_CPU_MIPSR6 | ||||||
|  |    ifeq ($(call ld-ifversion, -lt, 225000000, y),y) | ||||||
|  |      $(warning MIPS VDSO requires binutils >= 2.25) | ||||||
|  | -    obj-vdso-y := $(filter-out gettimeofday.o, $(obj-vdso-y)) | ||||||
|  | -    ccflags-vdso += -DDISABLE_MIPS_VDSO | ||||||
|  |    endif | ||||||
|  | +  obj-vdso-y := $(filter-out gettimeofday.o, $(obj-vdso-y)) | ||||||
|  | +  ccflags-vdso += -DDISABLE_MIPS_VDSO | ||||||
|  |  endif | ||||||
|  |   | ||||||
|  |  # VDSO linker flags. | ||||||
| @@ -0,0 +1,46 @@ | |||||||
|  | From: Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | Subject: usr: sanitize deps_initramfs list | ||||||
|  |  | ||||||
|  | If any filename in the intramfs dependency | ||||||
|  | list contains a colon, that causes a kernel | ||||||
|  | build error like this: | ||||||
|  |  | ||||||
|  | /devel/openwrt/build_dir/linux-ar71xx_generic/linux-3.6.6/usr/Makefile:58: *** multiple target patterns.  Stop. | ||||||
|  | make[5]: *** [usr] Error 2 | ||||||
|  |  | ||||||
|  | Fix it by removing such filenames from the | ||||||
|  | deps_initramfs list. | ||||||
|  |  | ||||||
|  | Signed-off-by: Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | --- | ||||||
|  |  usr/Makefile | 8 +++++--- | ||||||
|  |  1 file changed, 5 insertions(+), 3 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/usr/Makefile | ||||||
|  | +++ b/usr/Makefile | ||||||
|  | @@ -39,20 +39,22 @@ ifneq ($(wildcard $(obj)/$(datafile_d_y) | ||||||
|  |  	include $(obj)/$(datafile_d_y) | ||||||
|  |  endif | ||||||
|  |   | ||||||
|  | +deps_initramfs_sane := $(foreach v,$(deps_initramfs),$(if $(findstring :,$(v)),,$(v))) | ||||||
|  | + | ||||||
|  |  quiet_cmd_initfs = GEN     $@ | ||||||
|  |        cmd_initfs = $(initramfs) -o $@ $(ramfs-args) $(ramfs-input) | ||||||
|  |   | ||||||
|  |  targets := $(datafile_y) | ||||||
|  |   | ||||||
|  |  # do not try to update files included in initramfs | ||||||
|  | -$(deps_initramfs): ; | ||||||
|  | +$(deps_initramfs_sane): ; | ||||||
|  |   | ||||||
|  | -$(deps_initramfs): klibcdirs | ||||||
|  | +$(deps_initramfs_sane): klibcdirs | ||||||
|  |  # We rebuild initramfs_data.cpio if: | ||||||
|  |  # 1) Any included file is newer then initramfs_data.cpio | ||||||
|  |  # 2) There are changes in which files are included (added or deleted) | ||||||
|  |  # 3) If gen_init_cpio are newer than initramfs_data.cpio | ||||||
|  |  # 4) arguments to gen_initramfs.sh changes | ||||||
|  | -$(obj)/$(datafile_y): $(obj)/gen_init_cpio $(deps_initramfs) klibcdirs | ||||||
|  | +$(obj)/$(datafile_y): $(obj)/gen_init_cpio $(deps_initramfs_sane) klibcdirs | ||||||
|  |  	$(Q)$(initramfs) -l $(ramfs-input) > $(obj)/$(datafile_d_y) | ||||||
|  |  	$(call if_changed,initfs) | ||||||
| @@ -0,0 +1,20 @@ | |||||||
|  | From: Imre Kaloz <kaloz@openwrt.org> | ||||||
|  | Subject: [PATCH] hack: net: wireless: make the wl12xx glue code available with | ||||||
|  |  compat-wireless, too | ||||||
|  |  | ||||||
|  | Signed-off-by: Imre Kaloz <kaloz@openwrt.org> | ||||||
|  | --- | ||||||
|  |  drivers/net/wireless/ti/Kconfig | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/net/wireless/ti/Kconfig | ||||||
|  | +++ b/drivers/net/wireless/ti/Kconfig | ||||||
|  | @@ -19,7 +19,7 @@ source "drivers/net/wireless/ti/wlcore/K | ||||||
|  |   | ||||||
|  |  config WILINK_PLATFORM_DATA | ||||||
|  |  	bool "TI WiLink platform data" | ||||||
|  | -	depends on WLCORE_SDIO || WL1251_SDIO | ||||||
|  | +	depends on WLCORE_SDIO || WL1251_SDIO || ARCH_OMAP2PLUS | ||||||
|  |  	default y | ||||||
|  |  	---help--- | ||||||
|  |  	Small platform data bit needed to pass data to the sdio modules. | ||||||
| @@ -0,0 +1,32 @@ | |||||||
|  | From: David Heidelberger <david.heidelberger@ixit.cz> | ||||||
|  | Subject: uapi/kernel.h: glibc specific inclusion of sysinfo.h | ||||||
|  |  | ||||||
|  | including sysinfo.h from kernel.h makes no sense whatsoever, | ||||||
|  | but removing it breaks glibc's userspace header, | ||||||
|  | which includes kernel.h instead of sysinfo.h from their sys/sysinfo.h. | ||||||
|  | this seems to be a historical mistake. | ||||||
|  | on musl, including any header that uses kernel.h directly or indirectly | ||||||
|  | plus sys/sysinfo.h will produce a compile error due to redefinition of | ||||||
|  | struct sysinfo from sys/sysinfo.h. | ||||||
|  | so for now, only include it on glibc or when including from kernel | ||||||
|  | in order not to break their headers. | ||||||
|  |  | ||||||
|  | Signed-off-by: John Spencer <maillist-linux@barfooze.de> | ||||||
|  | Signed-off-by: David Heidelberger <david.heidelberger@ixit.cz> | ||||||
|  | Signed-off-by: Jonas Gorski <jogo@openwrt.org> | ||||||
|  | --- | ||||||
|  |  include/uapi/linux/kernel.h | 2 ++ | ||||||
|  |  1 file changed, 2 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/include/uapi/linux/kernel.h | ||||||
|  | +++ b/include/uapi/linux/kernel.h | ||||||
|  | @@ -2,7 +2,9 @@ | ||||||
|  |  #ifndef _UAPI_LINUX_KERNEL_H | ||||||
|  |  #define _UAPI_LINUX_KERNEL_H | ||||||
|  |   | ||||||
|  | +#if defined(__KERNEL__) || defined( __GLIBC__) | ||||||
|  |  #include <linux/sysinfo.h> | ||||||
|  | +#endif | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  |   * 'kernel.h' contains some often-used function prototypes etc | ||||||
| @@ -0,0 +1,105 @@ | |||||||
|  | From: David Heidelberger <david.heidelberger@ixit.cz> | ||||||
|  | Subject: uapi/libc-compat.h: do not rely on __GLIBC__ | ||||||
|  |  | ||||||
|  | Musl provides the same structs as glibc, but does not provide a define to | ||||||
|  | allow its detection. Since the absence of __GLIBC__ also can mean that it | ||||||
|  | is included from the kernel, change the __GLIBC__ detection to | ||||||
|  | !__KERNEL__, which should always be true when included from userspace. | ||||||
|  |  | ||||||
|  | Signed-off-by: John Spencer <maillist-linux@barfooze.de> | ||||||
|  | Tested-by: David Heidelberger <david.heidelberger@ixit.cz> | ||||||
|  | Signed-off-by: Jonas Gorski <jogo@openwrt.org> | ||||||
|  | --- | ||||||
|  |  include/uapi/linux/libc-compat.h | 18 +++++++++--------- | ||||||
|  |  1 file changed, 9 insertions(+), 9 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/include/uapi/linux/libc-compat.h | ||||||
|  | +++ b/include/uapi/linux/libc-compat.h | ||||||
|  | @@ -49,13 +49,13 @@ | ||||||
|  |  #ifndef _UAPI_LIBC_COMPAT_H | ||||||
|  |  #define _UAPI_LIBC_COMPAT_H | ||||||
|  |   | ||||||
|  | -/* We have included glibc headers... */ | ||||||
|  | -#if defined(__GLIBC__) | ||||||
|  | +/* We have included libc headers... */ | ||||||
|  | +#if !defined(__KERNEL__) | ||||||
|  |   | ||||||
|  | -/* Coordinate with glibc net/if.h header. */ | ||||||
|  | -#if defined(_NET_IF_H) && defined(__USE_MISC) | ||||||
|  | +/* Coordinate with libc net/if.h header. */ | ||||||
|  | +#if defined(_NET_IF_H) && (!defined(__GLIBC__) || defined(__USE_MISC)) | ||||||
|  |   | ||||||
|  | -/* GLIBC headers included first so don't define anything | ||||||
|  | +/* LIBC headers included first so don't define anything | ||||||
|  |   * that would already be defined. */ | ||||||
|  |   | ||||||
|  |  #define __UAPI_DEF_IF_IFCONF 0 | ||||||
|  | @@ -66,7 +66,11 @@ | ||||||
|  |  #define __UAPI_DEF_IF_NET_DEVICE_FLAGS 0 | ||||||
|  |  /* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */ | ||||||
|  |  #ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO | ||||||
|  | +#ifdef __GLIBC__ | ||||||
|  |  #define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1 | ||||||
|  | +#else | ||||||
|  | +#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 0 | ||||||
|  | +#endif | ||||||
|  |  #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ | ||||||
|  |   | ||||||
|  |  #else /* _NET_IF_H */ | ||||||
|  | @@ -86,10 +90,10 @@ | ||||||
|  |   | ||||||
|  |  #endif /* _NET_IF_H */ | ||||||
|  |   | ||||||
|  | -/* Coordinate with glibc netinet/in.h header. */ | ||||||
|  | +/* Coordinate with libc netinet/in.h header. */ | ||||||
|  |  #if defined(_NETINET_IN_H) | ||||||
|  |   | ||||||
|  | -/* GLIBC headers included first so don't define anything | ||||||
|  | +/* LIBC headers included first so don't define anything | ||||||
|  |   * that would already be defined. */ | ||||||
|  |  #define __UAPI_DEF_IN_ADDR		0 | ||||||
|  |  #define __UAPI_DEF_IN_IPPROTO		0 | ||||||
|  | @@ -103,7 +107,7 @@ | ||||||
|  |   * if the glibc code didn't define them. This guard matches | ||||||
|  |   * the guard in glibc/inet/netinet/in.h which defines the | ||||||
|  |   * additional in6_addr macros e.g. s6_addr16, and s6_addr32. */ | ||||||
|  | -#if defined(__USE_MISC) || defined (__USE_GNU) | ||||||
|  | +#if !defined(__GLIBC__) || defined(__USE_MISC) || defined (__USE_GNU) | ||||||
|  |  #define __UAPI_DEF_IN6_ADDR_ALT		0 | ||||||
|  |  #else | ||||||
|  |  #define __UAPI_DEF_IN6_ADDR_ALT		1 | ||||||
|  | @@ -118,7 +122,7 @@ | ||||||
|  |  #else | ||||||
|  |   | ||||||
|  |  /* Linux headers included first, and we must define everything | ||||||
|  | - * we need. The expectation is that glibc will check the | ||||||
|  | + * we need. The expectation is that the libc will check the | ||||||
|  |   * __UAPI_DEF_* defines and adjust appropriately. */ | ||||||
|  |  #define __UAPI_DEF_IN_ADDR		1 | ||||||
|  |  #define __UAPI_DEF_IN_IPPROTO		1 | ||||||
|  | @@ -128,7 +132,7 @@ | ||||||
|  |  #define __UAPI_DEF_IN_CLASS		1 | ||||||
|  |   | ||||||
|  |  #define __UAPI_DEF_IN6_ADDR		1 | ||||||
|  | -/* We unconditionally define the in6_addr macros and glibc must | ||||||
|  | +/* We unconditionally define the in6_addr macros and the libc must | ||||||
|  |   * coordinate. */ | ||||||
|  |  #define __UAPI_DEF_IN6_ADDR_ALT		1 | ||||||
|  |  #define __UAPI_DEF_SOCKADDR_IN6		1 | ||||||
|  | @@ -169,7 +173,7 @@ | ||||||
|  |  /* If we did not see any headers from any supported C libraries, | ||||||
|  |   * or we are being included in the kernel, then define everything | ||||||
|  |   * that we need. */ | ||||||
|  | -#else /* !defined(__GLIBC__) */ | ||||||
|  | +#else /* defined(__KERNEL__) */ | ||||||
|  |   | ||||||
|  |  /* Definitions for if.h */ | ||||||
|  |  #define __UAPI_DEF_IF_IFCONF 1 | ||||||
|  | @@ -209,6 +213,6 @@ | ||||||
|  |  /* Definitions for xattr.h */ | ||||||
|  |  #define __UAPI_DEF_XATTR		1 | ||||||
|  |   | ||||||
|  | -#endif /* __GLIBC__ */ | ||||||
|  | +#endif /* __KERNEL__ */ | ||||||
|  |   | ||||||
|  |  #endif /* _UAPI_LIBC_COMPAT_H */ | ||||||
| @@ -0,0 +1,65 @@ | |||||||
|  | From: David Heidelberger <david.heidelberger@ixit.cz> | ||||||
|  | Subject: uapi/if_ether.h: prevent redefinition of struct ethhdr | ||||||
|  |  | ||||||
|  | Musl provides its own ethhdr struct definition. Add a guard to prevent | ||||||
|  | its definition of the appropriate musl header has already been included. | ||||||
|  |  | ||||||
|  | Signed-off-by: John Spencer <maillist-linux@barfooze.de> | ||||||
|  | Tested-by: David Heidelberger <david.heidelberger@ixit.cz> | ||||||
|  | Signed-off-by: Jonas Gorski <jogo@openwrt.org> | ||||||
|  | --- | ||||||
|  |  include/uapi/linux/if_ether.h    |  3 +++ | ||||||
|  |  include/uapi/linux/libc-compat.h | 11 +++++++++++ | ||||||
|  |  2 files changed, 14 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/include/uapi/linux/if_ether.h | ||||||
|  | +++ b/include/uapi/linux/if_ether.h | ||||||
|  | @@ -23,6 +23,7 @@ | ||||||
|  |  #define _UAPI_LINUX_IF_ETHER_H | ||||||
|  |   | ||||||
|  |  #include <linux/types.h> | ||||||
|  | +#include <linux/libc-compat.h> | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  |   *	IEEE 802.3 Ethernet magic constants.  The frame sizes omit the preamble | ||||||
|  | @@ -149,11 +150,13 @@ | ||||||
|  |   *	This is an Ethernet frame header. | ||||||
|  |   */ | ||||||
|  |   | ||||||
|  | +#if __UAPI_DEF_ETHHDR | ||||||
|  |  struct ethhdr { | ||||||
|  |  	unsigned char	h_dest[ETH_ALEN];	/* destination eth addr	*/ | ||||||
|  |  	unsigned char	h_source[ETH_ALEN];	/* source ether addr	*/ | ||||||
|  |  	__be16		h_proto;		/* packet type ID field	*/ | ||||||
|  |  } __attribute__((packed)); | ||||||
|  | +#endif | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  #endif /* _UAPI_LINUX_IF_ETHER_H */ | ||||||
|  | --- a/include/uapi/linux/libc-compat.h | ||||||
|  | +++ b/include/uapi/linux/libc-compat.h | ||||||
|  | @@ -90,6 +90,14 @@ | ||||||
|  |   | ||||||
|  |  #endif /* _NET_IF_H */ | ||||||
|  |   | ||||||
|  | +/* musl defines the ethhdr struct itself in its netinet/if_ether.h. | ||||||
|  | + * Glibc just includes the kernel header and uses a different guard. */ | ||||||
|  | +#if defined(_NETINET_IF_ETHER_H) | ||||||
|  | +#define __UAPI_DEF_ETHHDR		0 | ||||||
|  | +#else | ||||||
|  | +#define __UAPI_DEF_ETHHDR		1 | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  |  /* Coordinate with libc netinet/in.h header. */ | ||||||
|  |  #if defined(_NETINET_IN_H) | ||||||
|  |   | ||||||
|  | @@ -185,6 +193,9 @@ | ||||||
|  |  /* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */ | ||||||
|  |  #define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1 | ||||||
|  |   | ||||||
|  | +/* Definitions for if_ether.h */ | ||||||
|  | +#define __UAPI_DEF_ETHHDR 		1 | ||||||
|  | + | ||||||
|  |  /* Definitions for in.h */ | ||||||
|  |  #define __UAPI_DEF_IN_ADDR		1 | ||||||
|  |  #define __UAPI_DEF_IN_IPPROTO		1 | ||||||
| @@ -0,0 +1,40 @@ | |||||||
|  | From: Mark Miller <mark@mirell.org> | ||||||
|  | Subject: mips: expose CONFIG_BOOT_RAW | ||||||
|  |  | ||||||
|  | This exposes the CONFIG_BOOT_RAW symbol in Kconfig. This is needed on | ||||||
|  | certain Broadcom chipsets running CFE in order to load the kernel. | ||||||
|  |  | ||||||
|  | Signed-off-by: Mark Miller <mark@mirell.org> | ||||||
|  | Acked-by: Rob Landley <rob@landley.net> | ||||||
|  | --- | ||||||
|  | --- a/arch/mips/Kconfig | ||||||
|  | +++ b/arch/mips/Kconfig | ||||||
|  | @@ -1066,9 +1066,6 @@ config FW_ARC | ||||||
|  |  config ARCH_MAY_HAVE_PC_FDC | ||||||
|  |  	bool | ||||||
|  |   | ||||||
|  | -config BOOT_RAW | ||||||
|  | -	bool | ||||||
|  | - | ||||||
|  |  config CEVT_BCM1480 | ||||||
|  |  	bool | ||||||
|  |   | ||||||
|  | @@ -2966,6 +2963,18 @@ choice | ||||||
|  |  		bool "Extend builtin kernel arguments with bootloader arguments" | ||||||
|  |  endchoice | ||||||
|  |   | ||||||
|  | +config BOOT_RAW | ||||||
|  | +	bool "Enable the kernel to be executed from the load address" | ||||||
|  | +	default n | ||||||
|  | +	help | ||||||
|  | +	 Allow the kernel to be executed from the load address for | ||||||
|  | +	 bootloaders which cannot read the ELF format. This places | ||||||
|  | +	 a jump to start_kernel at the load address. | ||||||
|  | + | ||||||
|  | +	 If unsure, say N. | ||||||
|  | + | ||||||
|  | + | ||||||
|  | + | ||||||
|  |  endmenu | ||||||
|  |   | ||||||
|  |  config LOCKDEP_SUPPORT | ||||||
| @@ -0,0 +1,22 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: mips: use -mno-branch-likely for kernel and userspace | ||||||
|  |  | ||||||
|  | saves ~11k kernel size after lzma and ~12k squashfs size in the | ||||||
|  |  | ||||||
|  | lede-commit: 41a039f46450ffae9483d6216422098669da2900 | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  arch/mips/Makefile | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/arch/mips/Makefile | ||||||
|  | +++ b/arch/mips/Makefile | ||||||
|  | @@ -90,7 +90,7 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin | ||||||
|  |  # machines may also.  Since BFD is incredibly buggy with respect to | ||||||
|  |  # crossformat linking we rely on the elf2ecoff tool for format conversion. | ||||||
|  |  # | ||||||
|  | -cflags-y			+= -G 0 -mno-abicalls -fno-pic -pipe | ||||||
|  | +cflags-y			+= -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely | ||||||
|  |  cflags-y			+= -msoft-float | ||||||
|  |  LDFLAGS_vmlinux			+= -G 0 -static -n -nostdlib | ||||||
|  |  KBUILD_AFLAGS_MODULE		+= -mlong-calls | ||||||
							
								
								
									
										137
									
								
								target/linux/generic/pending-4.14/304-mips_disable_fpu.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								target/linux/generic/pending-4.14/304-mips_disable_fpu.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,137 @@ | |||||||
|  | From:   Manuel Lauss <manuel.lauss@gmail.com> | ||||||
|  | Subject: [RFC PATCH v4 2/2] MIPS: make FPU emulator optional | ||||||
|  |  | ||||||
|  | This small patch makes the MIPS FPU emulator optional. The kernel | ||||||
|  | kills float-users on systems without a hardware FPU by sending a SIGILL. | ||||||
|  |  | ||||||
|  | Disabling the emulator shrinks vmlinux by about 54kBytes (32bit, | ||||||
|  | optimizing for size). | ||||||
|  |  | ||||||
|  | Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com> | ||||||
|  | --- | ||||||
|  | v4: rediffed because of patch 1/2, should now work with micromips as well | ||||||
|  | v3: updated patch description with size savings. | ||||||
|  | v2: incorporated changes suggested by Jonas Gorski | ||||||
|  |     force the fpu emulator on for micromips: relocating the parts | ||||||
|  |     of the mmips code in the emulator to other areas would be a | ||||||
|  |     much larger change; I went the cheap route instead with this. | ||||||
|  |  | ||||||
|  |  arch/mips/Kbuild                     |  2 +- | ||||||
|  |  arch/mips/Kconfig                    | 14 ++++++++++++++ | ||||||
|  |  arch/mips/include/asm/fpu.h          |  5 +++-- | ||||||
|  |  arch/mips/include/asm/fpu_emulator.h | 15 +++++++++++++++ | ||||||
|  |  4 files changed, 33 insertions(+), 3 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/arch/mips/Kconfig | ||||||
|  | +++ b/arch/mips/Kconfig | ||||||
|  | @@ -2890,6 +2890,20 @@ config MIPS_O32_FP64_SUPPORT | ||||||
|  |   | ||||||
|  |  	  If unsure, say N. | ||||||
|  |   | ||||||
|  | +config MIPS_FPU_EMULATOR | ||||||
|  | +	bool "MIPS FPU Emulator" | ||||||
|  | +	default y | ||||||
|  | +	help | ||||||
|  | +	  This option lets you disable the built-in MIPS FPU (Coprocessor 1) | ||||||
|  | +	  emulator, which handles floating-point instructions on processors | ||||||
|  | +	  without a hardware FPU.  It is generally a good idea to keep the | ||||||
|  | +	  emulator built-in, unless you are perfectly sure you have a | ||||||
|  | +	  complete soft-float environment.  With the emulator disabled, all | ||||||
|  | +	  users of float operations will be killed with an illegal instr- | ||||||
|  | +	  uction exception. | ||||||
|  | + | ||||||
|  | +	  Say Y, please. | ||||||
|  | + | ||||||
|  |  config USE_OF | ||||||
|  |  	bool | ||||||
|  |  	select OF | ||||||
|  | --- a/arch/mips/Makefile | ||||||
|  | +++ b/arch/mips/Makefile | ||||||
|  | @@ -319,7 +319,7 @@ OBJCOPYFLAGS		+= --remove-section=.regin | ||||||
|  |  head-y := arch/mips/kernel/head.o | ||||||
|  |   | ||||||
|  |  libs-y			+= arch/mips/lib/ | ||||||
|  | -libs-y			+= arch/mips/math-emu/ | ||||||
|  | +libs-$(CONFIG_MIPS_FPU_EMULATOR)	+= arch/mips/math-emu/ | ||||||
|  |   | ||||||
|  |  # See arch/mips/Kbuild for content of core part of the kernel | ||||||
|  |  core-y += arch/mips/ | ||||||
|  | --- a/arch/mips/include/asm/fpu.h | ||||||
|  | +++ b/arch/mips/include/asm/fpu.h | ||||||
|  | @@ -230,8 +230,10 @@ static inline int init_fpu(void) | ||||||
|  |  		/* Restore FRE */ | ||||||
|  |  		write_c0_config5(config5); | ||||||
|  |  		enable_fpu_hazard(); | ||||||
|  | -	} else | ||||||
|  | +	} else if (IS_ENABLED(CONFIG_MIPS_FPU_EMULATOR)) | ||||||
|  |  		fpu_emulator_init_fpu(); | ||||||
|  | +	else | ||||||
|  | +		ret = SIGILL; | ||||||
|  |   | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  | --- a/arch/mips/include/asm/fpu_emulator.h | ||||||
|  | +++ b/arch/mips/include/asm/fpu_emulator.h | ||||||
|  | @@ -30,6 +30,7 @@ | ||||||
|  |  #include <asm/local.h> | ||||||
|  |  #include <asm/processor.h> | ||||||
|  |   | ||||||
|  | +#ifdef CONFIG_MIPS_FPU_EMULATOR | ||||||
|  |  #ifdef CONFIG_DEBUG_FS | ||||||
|  |   | ||||||
|  |  struct mips_fpu_emulator_stats { | ||||||
|  | @@ -179,6 +180,16 @@ do {									\ | ||||||
|  |  extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, | ||||||
|  |  				    struct mips_fpu_struct *ctx, int has_fpu, | ||||||
|  |  				    void __user **fault_addr); | ||||||
|  | +#else	/* no CONFIG_MIPS_FPU_EMULATOR */ | ||||||
|  | +static inline int fpu_emulator_cop1Handler(struct pt_regs *xcp, | ||||||
|  | +				struct mips_fpu_struct *ctx, int has_fpu, | ||||||
|  | +				void __user **fault_addr) | ||||||
|  | +{ | ||||||
|  | +	*fault_addr = NULL; | ||||||
|  | +	return SIGILL;	/* we don't speak MIPS FPU */ | ||||||
|  | +} | ||||||
|  | +#endif	/* CONFIG_MIPS_FPU_EMULATOR */ | ||||||
|  | + | ||||||
|  |  void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr, | ||||||
|  |  		     struct task_struct *tsk); | ||||||
|  |  int process_fpemu_return(int sig, void __user *fault_addr, | ||||||
|  | --- a/arch/mips/include/asm/dsemul.h | ||||||
|  | +++ b/arch/mips/include/asm/dsemul.h | ||||||
|  | @@ -41,6 +41,7 @@ struct task_struct; | ||||||
|  |  extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir, | ||||||
|  |  		       unsigned long branch_pc, unsigned long cont_pc); | ||||||
|  |   | ||||||
|  | +#ifdef CONFIG_MIPS_FPU_EMULATOR | ||||||
|  |  /** | ||||||
|  |   * do_dsemulret() - Return from a delay slot 'emulation' frame | ||||||
|  |   * @xcp:	User thread register context. | ||||||
|  | @@ -88,5 +89,27 @@ extern bool dsemul_thread_rollback(struc | ||||||
|  |   * before @mm is freed in order to avoid memory leaks. | ||||||
|  |   */ | ||||||
|  |  extern void dsemul_mm_cleanup(struct mm_struct *mm); | ||||||
|  | +#else | ||||||
|  | +static inline bool do_dsemulret(struct pt_regs *xcp) | ||||||
|  | +{ | ||||||
|  | +	return false; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static inline bool dsemul_thread_cleanup(struct task_struct *tsk) | ||||||
|  | +{ | ||||||
|  | +	return false; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static inline bool dsemul_thread_rollback(struct pt_regs *regs) | ||||||
|  | +{ | ||||||
|  | +	return false; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static inline void dsemul_mm_cleanup(struct mm_struct *mm) | ||||||
|  | +{ | ||||||
|  | + | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +#endif | ||||||
|  |   | ||||||
|  |  #endif /* __MIPS_ASM_DSEMUL_H__ */ | ||||||
							
								
								
									
										366
									
								
								target/linux/generic/pending-4.14/305-mips_module_reloc.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										366
									
								
								target/linux/generic/pending-4.14/305-mips_module_reloc.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,366 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: mips: replace -mlong-calls with -mno-long-calls to make function calls faster in kernel modules to achieve this, try to | ||||||
|  |  | ||||||
|  | lede-commit: 3b3d64743ba2a874df9d70cd19e242205b0a788c | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  arch/mips/Makefile             |   5 + | ||||||
|  |  arch/mips/include/asm/module.h |   5 + | ||||||
|  |  arch/mips/kernel/module.c      | 279 ++++++++++++++++++++++++++++++++++++++++- | ||||||
|  |  3 files changed, 284 insertions(+), 5 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/arch/mips/Makefile | ||||||
|  | +++ b/arch/mips/Makefile | ||||||
|  | @@ -93,8 +93,13 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin | ||||||
|  |  cflags-y			+= -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely | ||||||
|  |  cflags-y			+= -msoft-float | ||||||
|  |  LDFLAGS_vmlinux			+= -G 0 -static -n -nostdlib | ||||||
|  | +ifdef CONFIG_64BIT | ||||||
|  |  KBUILD_AFLAGS_MODULE		+= -mlong-calls | ||||||
|  |  KBUILD_CFLAGS_MODULE		+= -mlong-calls | ||||||
|  | +else | ||||||
|  | +KBUILD_AFLAGS_MODULE		+= -mno-long-calls | ||||||
|  | +KBUILD_CFLAGS_MODULE		+= -mno-long-calls | ||||||
|  | +endif | ||||||
|  |   | ||||||
|  |  ifeq ($(CONFIG_RELOCATABLE),y) | ||||||
|  |  LDFLAGS_vmlinux			+= --emit-relocs | ||||||
|  | --- a/arch/mips/include/asm/module.h | ||||||
|  | +++ b/arch/mips/include/asm/module.h | ||||||
|  | @@ -12,6 +12,11 @@ struct mod_arch_specific { | ||||||
|  |  	const struct exception_table_entry *dbe_start; | ||||||
|  |  	const struct exception_table_entry *dbe_end; | ||||||
|  |  	struct mips_hi16 *r_mips_hi16_list; | ||||||
|  | + | ||||||
|  | +	void *phys_plt_tbl; | ||||||
|  | +	void *virt_plt_tbl; | ||||||
|  | +	unsigned int phys_plt_offset; | ||||||
|  | +	unsigned int virt_plt_offset; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  typedef uint8_t Elf64_Byte;		/* Type for a 8-bit quantity.  */ | ||||||
|  | --- a/arch/mips/kernel/module.c | ||||||
|  | +++ b/arch/mips/kernel/module.c | ||||||
|  | @@ -44,14 +44,221 @@ struct mips_hi16 { | ||||||
|  |  static LIST_HEAD(dbe_list); | ||||||
|  |  static DEFINE_SPINLOCK(dbe_lock); | ||||||
|  |   | ||||||
|  | -#ifdef MODULE_START | ||||||
|  | +/* | ||||||
|  | + * Get the potential max trampolines size required of the init and | ||||||
|  | + * non-init sections. Only used if we cannot find enough contiguous | ||||||
|  | + * physically mapped memory to put the module into. | ||||||
|  | + */ | ||||||
|  | +static unsigned int | ||||||
|  | +get_plt_size(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, | ||||||
|  | +             const char *secstrings, unsigned int symindex, bool is_init) | ||||||
|  | +{ | ||||||
|  | +	unsigned long ret = 0; | ||||||
|  | +	unsigned int i, j; | ||||||
|  | +	Elf_Sym *syms; | ||||||
|  | + | ||||||
|  | +	/* Everything marked ALLOC (this includes the exported symbols) */ | ||||||
|  | +	for (i = 1; i < hdr->e_shnum; ++i) { | ||||||
|  | +		unsigned int info = sechdrs[i].sh_info; | ||||||
|  | + | ||||||
|  | +		if (sechdrs[i].sh_type != SHT_REL | ||||||
|  | +		    && sechdrs[i].sh_type != SHT_RELA) | ||||||
|  | +			continue; | ||||||
|  | + | ||||||
|  | +		/* Not a valid relocation section? */ | ||||||
|  | +		if (info >= hdr->e_shnum) | ||||||
|  | +			continue; | ||||||
|  | + | ||||||
|  | +		/* Don't bother with non-allocated sections */ | ||||||
|  | +		if (!(sechdrs[info].sh_flags & SHF_ALLOC)) | ||||||
|  | +			continue; | ||||||
|  | + | ||||||
|  | +		/* If it's called *.init*, and we're not init, we're | ||||||
|  | +                   not interested */ | ||||||
|  | +		if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0) | ||||||
|  | +		    != is_init) | ||||||
|  | +			continue; | ||||||
|  | + | ||||||
|  | +		syms = (Elf_Sym *) sechdrs[symindex].sh_addr; | ||||||
|  | +		if (sechdrs[i].sh_type == SHT_REL) { | ||||||
|  | +			Elf_Mips_Rel *rel = (void *) sechdrs[i].sh_addr; | ||||||
|  | +			unsigned int size = sechdrs[i].sh_size / sizeof(*rel); | ||||||
|  | + | ||||||
|  | +			for (j = 0; j < size; ++j) { | ||||||
|  | +				Elf_Sym *sym; | ||||||
|  | + | ||||||
|  | +				if (ELF_MIPS_R_TYPE(rel[j]) != R_MIPS_26) | ||||||
|  | +					continue; | ||||||
|  | + | ||||||
|  | +				sym = syms + ELF_MIPS_R_SYM(rel[j]); | ||||||
|  | +				if (!is_init && sym->st_shndx != SHN_UNDEF) | ||||||
|  | +					continue; | ||||||
|  | + | ||||||
|  | +				ret += 4 * sizeof(int); | ||||||
|  | +			} | ||||||
|  | +		} else { | ||||||
|  | +			Elf_Mips_Rela *rela = (void *) sechdrs[i].sh_addr; | ||||||
|  | +			unsigned int size = sechdrs[i].sh_size / sizeof(*rela); | ||||||
|  | + | ||||||
|  | +			for (j = 0; j < size; ++j) { | ||||||
|  | +				Elf_Sym *sym; | ||||||
|  | + | ||||||
|  | +				if (ELF_MIPS_R_TYPE(rela[j]) != R_MIPS_26) | ||||||
|  | +					continue; | ||||||
|  | + | ||||||
|  | +				sym = syms + ELF_MIPS_R_SYM(rela[j]); | ||||||
|  | +				if (!is_init && sym->st_shndx != SHN_UNDEF) | ||||||
|  | +					continue; | ||||||
|  | + | ||||||
|  | +				ret += 4 * sizeof(int); | ||||||
|  | +			} | ||||||
|  | +		} | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return ret; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +#ifndef MODULE_START | ||||||
|  | +static void *alloc_phys(unsigned long size) | ||||||
|  | +{ | ||||||
|  | +	unsigned order; | ||||||
|  | +	struct page *page; | ||||||
|  | +	struct page *p; | ||||||
|  | + | ||||||
|  | +	size = PAGE_ALIGN(size); | ||||||
|  | +	order = get_order(size); | ||||||
|  | + | ||||||
|  | +	page = alloc_pages(GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN | | ||||||
|  | +			__GFP_THISNODE, order); | ||||||
|  | +	if (!page) | ||||||
|  | +		return NULL; | ||||||
|  | + | ||||||
|  | +	split_page(page, order); | ||||||
|  | + | ||||||
|  | +	/* mark all pages except for the last one */ | ||||||
|  | +	for (p = page; p + 1 < page + (size >> PAGE_SHIFT); ++p) | ||||||
|  | +		set_bit(PG_owner_priv_1, &p->flags); | ||||||
|  | + | ||||||
|  | +	for (p = page + (size >> PAGE_SHIFT); p < page + (1 << order); ++p) | ||||||
|  | +		__free_page(p); | ||||||
|  | + | ||||||
|  | +	return page_address(page); | ||||||
|  | +} | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  | +static void free_phys(void *ptr) | ||||||
|  | +{ | ||||||
|  | +	struct page *page; | ||||||
|  | +	bool free; | ||||||
|  | + | ||||||
|  | +	page = virt_to_page(ptr); | ||||||
|  | +	do { | ||||||
|  | +		free = test_and_clear_bit(PG_owner_priv_1, &page->flags); | ||||||
|  | +		__free_page(page); | ||||||
|  | +		page++; | ||||||
|  | +	} while (free); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | + | ||||||
|  |  void *module_alloc(unsigned long size) | ||||||
|  |  { | ||||||
|  | +#ifdef MODULE_START | ||||||
|  |  	return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END, | ||||||
|  |  				GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE, | ||||||
|  |  				__builtin_return_address(0)); | ||||||
|  | +#else | ||||||
|  | +	void *ptr; | ||||||
|  | + | ||||||
|  | +	if (size == 0) | ||||||
|  | +		return NULL; | ||||||
|  | + | ||||||
|  | +	ptr = alloc_phys(size); | ||||||
|  | + | ||||||
|  | +	/* If we failed to allocate physically contiguous memory, | ||||||
|  | +	 * fall back to regular vmalloc. The module loader code will | ||||||
|  | +	 * create jump tables to handle long jumps */ | ||||||
|  | +	if (!ptr) | ||||||
|  | +		return vmalloc(size); | ||||||
|  | + | ||||||
|  | +	return ptr; | ||||||
|  | +#endif | ||||||
|  |  } | ||||||
|  | + | ||||||
|  | +static inline bool is_phys_addr(void *ptr) | ||||||
|  | +{ | ||||||
|  | +#ifdef CONFIG_64BIT | ||||||
|  | +	return (KSEGX((unsigned long)ptr) == CKSEG0); | ||||||
|  | +#else | ||||||
|  | +	return (KSEGX(ptr) == KSEG0); | ||||||
|  |  #endif | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +/* Free memory returned from module_alloc */ | ||||||
|  | +void module_memfree(void *module_region) | ||||||
|  | +{ | ||||||
|  | +	if (is_phys_addr(module_region)) | ||||||
|  | +		free_phys(module_region); | ||||||
|  | +	else | ||||||
|  | +		vfree(module_region); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void *__module_alloc(int size, bool phys) | ||||||
|  | +{ | ||||||
|  | +	void *ptr; | ||||||
|  | + | ||||||
|  | +	if (phys) | ||||||
|  | +		ptr = kmalloc(size, GFP_KERNEL); | ||||||
|  | +	else | ||||||
|  | +		ptr = vmalloc(size); | ||||||
|  | +	return ptr; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void __module_free(void *ptr) | ||||||
|  | +{ | ||||||
|  | +	if (is_phys_addr(ptr)) | ||||||
|  | +		kfree(ptr); | ||||||
|  | +	else | ||||||
|  | +		vfree(ptr); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, | ||||||
|  | +			      char *secstrings, struct module *mod) | ||||||
|  | +{ | ||||||
|  | +	unsigned int symindex = 0; | ||||||
|  | +	unsigned int core_size, init_size; | ||||||
|  | +	int i; | ||||||
|  | + | ||||||
|  | +	mod->arch.phys_plt_offset = 0; | ||||||
|  | +	mod->arch.virt_plt_offset = 0; | ||||||
|  | +	mod->arch.phys_plt_tbl = NULL; | ||||||
|  | +	mod->arch.virt_plt_tbl = NULL; | ||||||
|  | + | ||||||
|  | +	if (IS_ENABLED(CONFIG_64BIT)) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  | +	for (i = 1; i < hdr->e_shnum; i++) | ||||||
|  | +		if (sechdrs[i].sh_type == SHT_SYMTAB) | ||||||
|  | +			symindex = i; | ||||||
|  | + | ||||||
|  | +	core_size = get_plt_size(hdr, sechdrs, secstrings, symindex, false); | ||||||
|  | +	init_size = get_plt_size(hdr, sechdrs, secstrings, symindex, true); | ||||||
|  | + | ||||||
|  | +	if ((core_size + init_size) == 0) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  | +	mod->arch.phys_plt_tbl = __module_alloc(core_size + init_size, 1); | ||||||
|  | +	if (!mod->arch.phys_plt_tbl) | ||||||
|  | +		return -ENOMEM; | ||||||
|  | + | ||||||
|  | +	mod->arch.virt_plt_tbl = __module_alloc(core_size + init_size, 0); | ||||||
|  | +	if (!mod->arch.virt_plt_tbl) { | ||||||
|  | +		__module_free(mod->arch.phys_plt_tbl); | ||||||
|  | +		mod->arch.phys_plt_tbl = NULL; | ||||||
|  | +		return -ENOMEM; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  |   | ||||||
|  |  static int apply_r_mips_none(struct module *me, u32 *location, | ||||||
|  |  			     u32 base, Elf_Addr v, bool rela) | ||||||
|  | @@ -67,9 +274,40 @@ static int apply_r_mips_32(struct module | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static Elf_Addr add_plt_entry_to(unsigned *plt_offset, | ||||||
|  | +				 void *start, Elf_Addr v) | ||||||
|  | +{ | ||||||
|  | +	unsigned *tramp = start + *plt_offset; | ||||||
|  | +	*plt_offset += 4 * sizeof(int); | ||||||
|  | + | ||||||
|  | +	/* adjust carry for addiu */ | ||||||
|  | +	if (v & 0x00008000) | ||||||
|  | +		v += 0x10000; | ||||||
|  | + | ||||||
|  | +	tramp[0] = 0x3c190000 | (v >> 16);      /* lui t9, hi16 */ | ||||||
|  | +	tramp[1] = 0x27390000 | (v & 0xffff);   /* addiu t9, t9, lo16 */ | ||||||
|  | +	tramp[2] = 0x03200008;                  /* jr t9 */ | ||||||
|  | +	tramp[3] = 0x00000000;                  /* nop */ | ||||||
|  | + | ||||||
|  | +	return (Elf_Addr) tramp; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static Elf_Addr add_plt_entry(struct module *me, void *location, Elf_Addr v) | ||||||
|  | +{ | ||||||
|  | +	if (is_phys_addr(location)) | ||||||
|  | +		return add_plt_entry_to(&me->arch.phys_plt_offset, | ||||||
|  | +				me->arch.phys_plt_tbl, v); | ||||||
|  | +	else | ||||||
|  | +		return add_plt_entry_to(&me->arch.virt_plt_offset, | ||||||
|  | +				me->arch.virt_plt_tbl, v); | ||||||
|  | + | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static int apply_r_mips_26(struct module *me, u32 *location, | ||||||
|  |  			   u32 base, Elf_Addr v, bool rela) | ||||||
|  |  { | ||||||
|  | +	u32 ofs = base & 0x03ffffff; | ||||||
|  | + | ||||||
|  |  	if (v % 4) { | ||||||
|  |  		pr_err("module %s: dangerous R_MIPS_26 relocation\n", | ||||||
|  |  		       me->name); | ||||||
|  | @@ -77,13 +315,17 @@ static int apply_r_mips_26(struct module | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { | ||||||
|  | -		pr_err("module %s: relocation overflow\n", | ||||||
|  | -		       me->name); | ||||||
|  | -		return -ENOEXEC; | ||||||
|  | +		v = add_plt_entry(me, location, v + (ofs << 2)); | ||||||
|  | +		if (!v) { | ||||||
|  | +			pr_err("module %s: relocation overflow\n", | ||||||
|  | +			       me->name); | ||||||
|  | +			return -ENOEXEC; | ||||||
|  | +		} | ||||||
|  | +		ofs = 0; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	*location = (*location & ~0x03ffffff) | | ||||||
|  | -		    ((base + (v >> 2)) & 0x03ffffff); | ||||||
|  | +		    ((ofs + (v >> 2)) & 0x03ffffff); | ||||||
|  |   | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  | @@ -459,9 +701,36 @@ int module_finalize(const Elf_Ehdr *hdr, | ||||||
|  |  		list_add(&me->arch.dbe_list, &dbe_list); | ||||||
|  |  		spin_unlock_irq(&dbe_lock); | ||||||
|  |  	} | ||||||
|  | + | ||||||
|  | +	/* Get rid of the fixup trampoline if we're running the module | ||||||
|  | +	 * from physically mapped address space */ | ||||||
|  | +	if (me->arch.phys_plt_offset == 0) { | ||||||
|  | +		__module_free(me->arch.phys_plt_tbl); | ||||||
|  | +		me->arch.phys_plt_tbl = NULL; | ||||||
|  | +	} | ||||||
|  | +	if (me->arch.virt_plt_offset == 0) { | ||||||
|  | +		__module_free(me->arch.virt_plt_tbl); | ||||||
|  | +		me->arch.virt_plt_tbl = NULL; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +void module_arch_freeing_init(struct module *mod) | ||||||
|  | +{ | ||||||
|  | +	if (mod->state == MODULE_STATE_LIVE) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	if (mod->arch.phys_plt_tbl) { | ||||||
|  | +		__module_free(mod->arch.phys_plt_tbl); | ||||||
|  | +		mod->arch.phys_plt_tbl = NULL; | ||||||
|  | +	} | ||||||
|  | +	if (mod->arch.virt_plt_tbl) { | ||||||
|  | +		__module_free(mod->arch.virt_plt_tbl); | ||||||
|  | +		mod->arch.virt_plt_tbl = NULL; | ||||||
|  | +	} | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  void module_arch_cleanup(struct module *mod) | ||||||
|  |  { | ||||||
|  |  	spin_lock_irq(&dbe_lock); | ||||||
| @@ -0,0 +1,106 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: [PATCH] mips: allow the compiler to optimize memset, memcmp, memcpy  for better performance and (in some instances) smaller code | ||||||
|  |  | ||||||
|  | lede-commit: 07e59c7bc7f375f792ec9734be42fe4fa391a8bb | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  arch/mips/boot/compressed/Makefile |  3 ++- | ||||||
|  |  arch/mips/include/asm/string.h     | 38 ++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  arch/mips/lib/Makefile             |  2 +- | ||||||
|  |  arch/mips/lib/memcmp.c             | 22 ++++++++++++++++++++++ | ||||||
|  |  4 files changed, 63 insertions(+), 2 deletions(-) | ||||||
|  |  create mode 100644 arch/mips/lib/memcmp.c | ||||||
|  |  | ||||||
|  | --- a/arch/mips/boot/compressed/Makefile | ||||||
|  | +++ b/arch/mips/boot/compressed/Makefile | ||||||
|  | @@ -23,7 +23,8 @@ KBUILD_CFLAGS := $(filter-out -pg, $(KBU | ||||||
|  |  KBUILD_CFLAGS := $(filter-out -fstack-protector, $(KBUILD_CFLAGS)) | ||||||
|  |   | ||||||
|  |  KBUILD_CFLAGS := $(KBUILD_CFLAGS) -D__KERNEL__ \ | ||||||
|  | -	-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull" | ||||||
|  | +	-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) -D"VMLINUX_LOAD_ADDRESS_ULL=$(VMLINUX_LOAD_ADDRESS)ull" \ | ||||||
|  | +	-D__ZBOOT__ | ||||||
|  |   | ||||||
|  |  KBUILD_AFLAGS := $(KBUILD_AFLAGS) -D__ASSEMBLY__ \ | ||||||
|  |  	-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \ | ||||||
|  | --- a/arch/mips/include/asm/string.h | ||||||
|  | +++ b/arch/mips/include/asm/string.h | ||||||
|  | @@ -140,4 +140,42 @@ extern void *memcpy(void *__to, __const_ | ||||||
|  |  #define __HAVE_ARCH_MEMMOVE | ||||||
|  |  extern void *memmove(void *__dest, __const__ void *__src, size_t __n); | ||||||
|  |   | ||||||
|  | +#ifndef __ZBOOT__ | ||||||
|  | +#define memset(__s, __c, len)					\ | ||||||
|  | +({								\ | ||||||
|  | +	size_t __len = (len);					\ | ||||||
|  | +	void *__ret;						\ | ||||||
|  | +	if (__builtin_constant_p(len) && __len >= 64)		\ | ||||||
|  | +		__ret = memset((__s), (__c), __len);		\ | ||||||
|  | +	else							\ | ||||||
|  | +		__ret = __builtin_memset((__s), (__c), __len);	\ | ||||||
|  | +	__ret;							\ | ||||||
|  | +}) | ||||||
|  | + | ||||||
|  | +#define memcpy(dst, src, len)					\ | ||||||
|  | +({								\ | ||||||
|  | +	size_t __len = (len);					\ | ||||||
|  | +	void *__ret;						\ | ||||||
|  | +	if (__builtin_constant_p(len) && __len >= 64)		\ | ||||||
|  | +		__ret = memcpy((dst), (src), __len);		\ | ||||||
|  | +	else							\ | ||||||
|  | +		__ret = __builtin_memcpy((dst), (src), __len);	\ | ||||||
|  | +	__ret;							\ | ||||||
|  | +}) | ||||||
|  | + | ||||||
|  | +#define memmove(dst, src, len)					\ | ||||||
|  | +({								\ | ||||||
|  | +	size_t __len = (len);					\ | ||||||
|  | +	void *__ret;						\ | ||||||
|  | +	if (__builtin_constant_p(len) && __len >= 64)		\ | ||||||
|  | +		__ret = memmove((dst), (src), __len);		\ | ||||||
|  | +	else							\ | ||||||
|  | +		__ret = __builtin_memmove((dst), (src), __len);	\ | ||||||
|  | +	__ret;							\ | ||||||
|  | +}) | ||||||
|  | + | ||||||
|  | +#define __HAVE_ARCH_MEMCMP | ||||||
|  | +#define memcmp(src1, src2, len) __builtin_memcmp((src1), (src2), (len)) | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  |  #endif /* _ASM_STRING_H */ | ||||||
|  | --- a/arch/mips/lib/Makefile | ||||||
|  | +++ b/arch/mips/lib/Makefile | ||||||
|  | @@ -5,7 +5,7 @@ | ||||||
|  |   | ||||||
|  |  lib-y	+= bitops.o csum_partial.o delay.o memcpy.o memset.o \ | ||||||
|  |  	   mips-atomic.o strncpy_user.o \ | ||||||
|  | -	   strnlen_user.o uncached.o | ||||||
|  | +	   strnlen_user.o uncached.o memcmp.o | ||||||
|  |   | ||||||
|  |  obj-y			+= iomap.o iomap_copy.o | ||||||
|  |  obj-$(CONFIG_PCI)	+= iomap-pci.o | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/arch/mips/lib/memcmp.c | ||||||
|  | @@ -0,0 +1,22 @@ | ||||||
|  | +/* | ||||||
|  | + *  copied from linux/lib/string.c | ||||||
|  | + * | ||||||
|  | + *  Copyright (C) 1991, 1992  Linus Torvalds | ||||||
|  | + */ | ||||||
|  | + | ||||||
|  | +#include <linux/module.h> | ||||||
|  | +#include <linux/string.h> | ||||||
|  | + | ||||||
|  | +#undef memcmp | ||||||
|  | +int memcmp(const void *cs, const void *ct, size_t count) | ||||||
|  | +{ | ||||||
|  | +	const unsigned char *su1, *su2; | ||||||
|  | +	int res = 0; | ||||||
|  | + | ||||||
|  | +	for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) | ||||||
|  | +		if ((res = *su1 - *su2) != 0) | ||||||
|  | +			break; | ||||||
|  | +	return res; | ||||||
|  | +} | ||||||
|  | +EXPORT_SYMBOL(memcmp); | ||||||
|  | + | ||||||
| @@ -0,0 +1,19 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: kernel: adjust mips highmem offset to avoid the need for -mlong-calls on systems with >256M RAM | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  arch/mips/include/asm/mach-generic/spaces.h | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/arch/mips/include/asm/mach-generic/spaces.h | ||||||
|  | +++ b/arch/mips/include/asm/mach-generic/spaces.h | ||||||
|  | @@ -46,7 +46,7 @@ | ||||||
|  |   * Memory above this physical address will be considered highmem. | ||||||
|  |   */ | ||||||
|  |  #ifndef HIGHMEM_START | ||||||
|  | -#define HIGHMEM_START		_AC(0x20000000, UL) | ||||||
|  | +#define HIGHMEM_START		_AC(0x10000000, UL) | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  |  #endif /* CONFIG_32BIT */ | ||||||
							
								
								
									
										22
									
								
								target/linux/generic/pending-4.14/308-mips32r2_tune.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								target/linux/generic/pending-4.14/308-mips32r2_tune.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: kernel: add -mtune=34kc to MIPS CFLAGS when building for mips32r2 | ||||||
|  |  | ||||||
|  | This provides a good tradeoff across at least 24Kc-74Kc, while also | ||||||
|  | producing smaller code. | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  arch/mips/Makefile | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/arch/mips/Makefile | ||||||
|  | +++ b/arch/mips/Makefile | ||||||
|  | @@ -162,7 +162,7 @@ cflags-$(CONFIG_CPU_R4X00)	+= -march=r46 | ||||||
|  |  cflags-$(CONFIG_CPU_TX49XX)	+= -march=r4600 -Wa,--trap | ||||||
|  |  cflags-$(CONFIG_CPU_MIPS32_R1)	+= $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ | ||||||
|  |  			-Wa,-mips32 -Wa,--trap | ||||||
|  | -cflags-$(CONFIG_CPU_MIPS32_R2)	+= $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ | ||||||
|  | +cflags-$(CONFIG_CPU_MIPS32_R2)	+= $(call cc-option,-march=mips32r2 -mtune=34kc,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ | ||||||
|  |  			-Wa,-mips32r2 -Wa,--trap | ||||||
|  |  cflags-$(CONFIG_CPU_MIPS32_R6)	+= -march=mips32r6 -Wa,--trap -modd-spreg | ||||||
|  |  cflags-$(CONFIG_CPU_MIPS64_R1)	+= $(call cc-option,-march=mips64,-mips64 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) \ | ||||||
| @@ -0,0 +1,22 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: fix errors in unresolved weak symbols on arm | ||||||
|  |  | ||||||
|  | lede-commit: 570699d4838a907c3ef9f2819bf19eb72997b32f | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  arch/arm/kernel/module.c | 4 ++++ | ||||||
|  |  1 file changed, 4 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/arch/arm/kernel/module.c | ||||||
|  | +++ b/arch/arm/kernel/module.c | ||||||
|  | @@ -95,6 +95,10 @@ apply_relocate(Elf32_Shdr *sechdrs, cons | ||||||
|  |  			return -ENOEXEC; | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  | +		if ((IS_ERR_VALUE(sym->st_value) || !sym->st_value) && | ||||||
|  | +		    ELF_ST_BIND(sym->st_info) == STB_WEAK) | ||||||
|  | +			continue; | ||||||
|  | + | ||||||
|  |  		loc = dstsec->sh_addr + rel->r_offset; | ||||||
|  |   | ||||||
|  |  		switch (ELF32_R_TYPE(rel->r_info)) { | ||||||
| @@ -0,0 +1,272 @@ | |||||||
|  | From: Yousong Zhou <yszhou4tech@gmail.com> | ||||||
|  | Subject: MIPS: kexec: Accept command line parameters from userspace. | ||||||
|  |  | ||||||
|  | Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com> | ||||||
|  | --- | ||||||
|  |  arch/mips/kernel/machine_kexec.c   |  153 +++++++++++++++++++++++++++++++----- | ||||||
|  |  arch/mips/kernel/machine_kexec.h   |   20 +++++ | ||||||
|  |  arch/mips/kernel/relocate_kernel.S |   21 +++-- | ||||||
|  |  3 files changed, 167 insertions(+), 27 deletions(-) | ||||||
|  |  create mode 100644 arch/mips/kernel/machine_kexec.h | ||||||
|  |  | ||||||
|  | --- a/arch/mips/kernel/machine_kexec.c | ||||||
|  | +++ b/arch/mips/kernel/machine_kexec.c | ||||||
|  | @@ -10,14 +10,11 @@ | ||||||
|  |  #include <linux/mm.h> | ||||||
|  |  #include <linux/delay.h> | ||||||
|  |   | ||||||
|  | +#include <asm/bootinfo.h> | ||||||
|  |  #include <asm/cacheflush.h> | ||||||
|  |  #include <asm/page.h> | ||||||
|  | - | ||||||
|  | -extern const unsigned char relocate_new_kernel[]; | ||||||
|  | -extern const size_t relocate_new_kernel_size; | ||||||
|  | - | ||||||
|  | -extern unsigned long kexec_start_address; | ||||||
|  | -extern unsigned long kexec_indirection_page; | ||||||
|  | +#include <asm/uaccess.h> | ||||||
|  | +#include "machine_kexec.h" | ||||||
|  |   | ||||||
|  |  int (*_machine_kexec_prepare)(struct kimage *) = NULL; | ||||||
|  |  void (*_machine_kexec_shutdown)(void) = NULL; | ||||||
|  | @@ -28,6 +25,99 @@ atomic_t kexec_ready_to_reboot = ATOMIC_ | ||||||
|  |  void (*_crash_smp_send_stop)(void) = NULL; | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  | +static void machine_kexec_print_args(void) | ||||||
|  | +{ | ||||||
|  | +	unsigned long argc = (int)kexec_args[0]; | ||||||
|  | +	int i; | ||||||
|  | + | ||||||
|  | +	pr_info("kexec_args[0] (argc): %lu\n", argc); | ||||||
|  | +	pr_info("kexec_args[1] (argv): %p\n", (void *)kexec_args[1]); | ||||||
|  | +	pr_info("kexec_args[2] (env ): %p\n", (void *)kexec_args[2]); | ||||||
|  | +	pr_info("kexec_args[3] (desc): %p\n", (void *)kexec_args[3]); | ||||||
|  | + | ||||||
|  | +	for (i = 0; i < argc; i++) { | ||||||
|  | +		pr_info("kexec_argv[%d] = %p, %s\n", | ||||||
|  | +				i, kexec_argv[i], kexec_argv[i]); | ||||||
|  | +	} | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void machine_kexec_init_argv(struct kimage *image) | ||||||
|  | +{ | ||||||
|  | +	void __user *buf = NULL; | ||||||
|  | +	size_t bufsz; | ||||||
|  | +	size_t size; | ||||||
|  | +	int i; | ||||||
|  | + | ||||||
|  | +	bufsz = 0; | ||||||
|  | +	for (i = 0; i < image->nr_segments; i++) { | ||||||
|  | +		struct kexec_segment *seg; | ||||||
|  | + | ||||||
|  | +		seg = &image->segment[i]; | ||||||
|  | +		if (seg->bufsz < 6) | ||||||
|  | +			continue; | ||||||
|  | + | ||||||
|  | +		if (strncmp((char *) seg->buf, "kexec ", 6)) | ||||||
|  | +			continue; | ||||||
|  | + | ||||||
|  | +		buf = seg->buf; | ||||||
|  | +		bufsz = seg->bufsz; | ||||||
|  | +		break; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	if (!buf) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	size = KEXEC_COMMAND_LINE_SIZE; | ||||||
|  | +	size = min(size, bufsz); | ||||||
|  | +	if (size < bufsz) | ||||||
|  | +		pr_warn("kexec command line truncated to %zd bytes\n", size); | ||||||
|  | + | ||||||
|  | +	/* Copy to kernel space */ | ||||||
|  | +	copy_from_user(kexec_argv_buf, buf, size); | ||||||
|  | +	kexec_argv_buf[size - 1] = 0; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void machine_kexec_parse_argv(struct kimage *image) | ||||||
|  | +{ | ||||||
|  | +	char *reboot_code_buffer; | ||||||
|  | +	int reloc_delta; | ||||||
|  | +	char *ptr; | ||||||
|  | +	int argc; | ||||||
|  | +	int i; | ||||||
|  | + | ||||||
|  | +	ptr = kexec_argv_buf; | ||||||
|  | +	argc = 0; | ||||||
|  | + | ||||||
|  | +	/* | ||||||
|  | +	 * convert command line string to array of parameters | ||||||
|  | +	 * (as bootloader does). | ||||||
|  | +	 */ | ||||||
|  | +	while (ptr && *ptr && (KEXEC_MAX_ARGC > argc)) { | ||||||
|  | +		if (*ptr == ' ') { | ||||||
|  | +			*ptr++ = '\0'; | ||||||
|  | +			continue; | ||||||
|  | +		} | ||||||
|  | + | ||||||
|  | +		kexec_argv[argc++] = ptr; | ||||||
|  | +		ptr = strchr(ptr, ' '); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	if (!argc) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	kexec_args[0] = argc; | ||||||
|  | +	kexec_args[1] = (unsigned long)kexec_argv; | ||||||
|  | +	kexec_args[2] = 0; | ||||||
|  | +	kexec_args[3] = 0; | ||||||
|  | + | ||||||
|  | +	reboot_code_buffer = page_address(image->control_code_page); | ||||||
|  | +	reloc_delta = reboot_code_buffer - (char *)kexec_relocate_new_kernel; | ||||||
|  | + | ||||||
|  | +	kexec_args[1] += reloc_delta; | ||||||
|  | +	for (i = 0; i < argc; i++) | ||||||
|  | +		kexec_argv[i] += reloc_delta; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static void kexec_image_info(const struct kimage *kimage) | ||||||
|  |  { | ||||||
|  |  	unsigned long i; | ||||||
|  | @@ -52,6 +142,18 @@ int | ||||||
|  |  machine_kexec_prepare(struct kimage *kimage) | ||||||
|  |  { | ||||||
|  |  	kexec_image_info(kimage); | ||||||
|  | +	/* | ||||||
|  | +	 * Whenever arguments passed from kexec-tools, Init the arguments as | ||||||
|  | +	 * the original ones to try avoiding booting failure. | ||||||
|  | +	 */ | ||||||
|  | + | ||||||
|  | +	kexec_args[0] = fw_arg0; | ||||||
|  | +	kexec_args[1] = fw_arg1; | ||||||
|  | +	kexec_args[2] = fw_arg2; | ||||||
|  | +	kexec_args[3] = fw_arg3; | ||||||
|  | + | ||||||
|  | +	machine_kexec_init_argv(kimage); | ||||||
|  | +	machine_kexec_parse_argv(kimage); | ||||||
|  |   | ||||||
|  |  	if (_machine_kexec_prepare) | ||||||
|  |  		return _machine_kexec_prepare(kimage); | ||||||
|  | @@ -89,10 +191,12 @@ machine_kexec(struct kimage *image) | ||||||
|  |  	unsigned long *ptr; | ||||||
|  |   | ||||||
|  |  	reboot_code_buffer = | ||||||
|  | -	  (unsigned long)page_address(image->control_code_page); | ||||||
|  | +		(unsigned long)page_address(image->control_code_page); | ||||||
|  | +	pr_info("reboot_code_buffer = %p\n", (void *)reboot_code_buffer); | ||||||
|  |   | ||||||
|  |  	kexec_start_address = | ||||||
|  |  		(unsigned long) phys_to_virt(image->start); | ||||||
|  | +	pr_info("kexec_start_address = %p\n", (void *)kexec_start_address); | ||||||
|  |   | ||||||
|  |  	if (image->type == KEXEC_TYPE_DEFAULT) { | ||||||
|  |  		kexec_indirection_page = | ||||||
|  | @@ -100,9 +204,19 @@ machine_kexec(struct kimage *image) | ||||||
|  |  	} else { | ||||||
|  |  		kexec_indirection_page = (unsigned long)&image->head; | ||||||
|  |  	} | ||||||
|  | +	pr_info("kexec_indirection_page = %p\n", (void *)kexec_indirection_page); | ||||||
|  |   | ||||||
|  | -	memcpy((void*)reboot_code_buffer, relocate_new_kernel, | ||||||
|  | -	       relocate_new_kernel_size); | ||||||
|  | +	pr_info("Where is memcpy: %p\n", memcpy); | ||||||
|  | +	pr_info("kexec_relocate_new_kernel = %p, kexec_relocate_new_kernel_end = %p\n", | ||||||
|  | +		(void *)kexec_relocate_new_kernel, &kexec_relocate_new_kernel_end); | ||||||
|  | +	pr_info("Copy %lu bytes from %p to %p\n", KEXEC_RELOCATE_NEW_KERNEL_SIZE, | ||||||
|  | +		(void *)kexec_relocate_new_kernel, (void *)reboot_code_buffer); | ||||||
|  | +	memcpy((void*)reboot_code_buffer, kexec_relocate_new_kernel, | ||||||
|  | +	       KEXEC_RELOCATE_NEW_KERNEL_SIZE); | ||||||
|  | + | ||||||
|  | +	pr_info("Before _print_args().\n"); | ||||||
|  | +	machine_kexec_print_args(); | ||||||
|  | +	pr_info("Before eval loop.\n"); | ||||||
|  |   | ||||||
|  |  	/* | ||||||
|  |  	 * The generic kexec code builds a page list with physical | ||||||
|  | @@ -121,15 +235,16 @@ machine_kexec(struct kimage *image) | ||||||
|  |  	/* | ||||||
|  |  	 * we do not want to be bothered. | ||||||
|  |  	 */ | ||||||
|  | +	pr_info("Before irq_disable.\n"); | ||||||
|  |  	local_irq_disable(); | ||||||
|  |   | ||||||
|  | -	printk("Will call new kernel at %08lx\n", image->start); | ||||||
|  | -	printk("Bye ...\n"); | ||||||
|  | +	pr_info("Will call new kernel at %08lx\n", image->start); | ||||||
|  | +	pr_info("Bye ...\n"); | ||||||
|  |  	__flush_cache_all(); | ||||||
|  |  #ifdef CONFIG_SMP | ||||||
|  |  	/* All secondary cpus now may jump to kexec_wait cycle */ | ||||||
|  |  	relocated_kexec_smp_wait = reboot_code_buffer + | ||||||
|  | -		(void *)(kexec_smp_wait - relocate_new_kernel); | ||||||
|  | +		(void *)(kexec_smp_wait - kexec_relocate_new_kernel); | ||||||
|  |  	smp_wmb(); | ||||||
|  |  	atomic_set(&kexec_ready_to_reboot, 1); | ||||||
|  |  #endif | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/arch/mips/kernel/machine_kexec.h | ||||||
|  | @@ -0,0 +1,20 @@ | ||||||
|  | +#ifndef _MACHINE_KEXEC_H | ||||||
|  | +#define _MACHINE_KEXEC_H | ||||||
|  | + | ||||||
|  | +#ifndef __ASSEMBLY__ | ||||||
|  | +extern const unsigned char kexec_relocate_new_kernel[]; | ||||||
|  | +extern unsigned long kexec_relocate_new_kernel_end; | ||||||
|  | +extern unsigned long kexec_start_address; | ||||||
|  | +extern unsigned long kexec_indirection_page; | ||||||
|  | + | ||||||
|  | +extern char kexec_argv_buf[]; | ||||||
|  | +extern char *kexec_argv[]; | ||||||
|  | + | ||||||
|  | +#define KEXEC_RELOCATE_NEW_KERNEL_SIZE	((unsigned long)&kexec_relocate_new_kernel_end - (unsigned long)kexec_relocate_new_kernel) | ||||||
|  | +#endif /* !__ASSEMBLY__ */ | ||||||
|  | + | ||||||
|  | +#define KEXEC_COMMAND_LINE_SIZE		256 | ||||||
|  | +#define KEXEC_ARGV_SIZE			(KEXEC_COMMAND_LINE_SIZE / 16) | ||||||
|  | +#define KEXEC_MAX_ARGC			(KEXEC_ARGV_SIZE / sizeof(long)) | ||||||
|  | + | ||||||
|  | +#endif | ||||||
|  | --- a/arch/mips/kernel/relocate_kernel.S | ||||||
|  | +++ b/arch/mips/kernel/relocate_kernel.S | ||||||
|  | @@ -12,8 +12,9 @@ | ||||||
|  |  #include <asm/mipsregs.h> | ||||||
|  |  #include <asm/stackframe.h> | ||||||
|  |  #include <asm/addrspace.h> | ||||||
|  | +#include "machine_kexec.h" | ||||||
|  |   | ||||||
|  | -LEAF(relocate_new_kernel) | ||||||
|  | +LEAF(kexec_relocate_new_kernel) | ||||||
|  |  	PTR_L a0,	arg0 | ||||||
|  |  	PTR_L a1,	arg1 | ||||||
|  |  	PTR_L a2,	arg2 | ||||||
|  | @@ -98,7 +99,7 @@ done: | ||||||
|  |  #endif | ||||||
|  |  	/* jump to kexec_start_address */ | ||||||
|  |  	j		s1 | ||||||
|  | -	END(relocate_new_kernel) | ||||||
|  | +	END(kexec_relocate_new_kernel) | ||||||
|  |   | ||||||
|  |  #ifdef CONFIG_SMP | ||||||
|  |  /* | ||||||
|  | @@ -184,9 +185,15 @@ kexec_indirection_page: | ||||||
|  |  	PTR		0 | ||||||
|  |  	.size		kexec_indirection_page, PTRSIZE | ||||||
|  |   | ||||||
|  | -relocate_new_kernel_end: | ||||||
|  | +kexec_argv_buf: | ||||||
|  | +	EXPORT(kexec_argv_buf) | ||||||
|  | +	.skip		KEXEC_COMMAND_LINE_SIZE | ||||||
|  | +	.size		kexec_argv_buf, KEXEC_COMMAND_LINE_SIZE | ||||||
|  | + | ||||||
|  | +kexec_argv: | ||||||
|  | +	EXPORT(kexec_argv) | ||||||
|  | +	.skip		KEXEC_ARGV_SIZE | ||||||
|  | +	.size		kexec_argv, KEXEC_ARGV_SIZE | ||||||
|  |   | ||||||
|  | -relocate_new_kernel_size: | ||||||
|  | -	EXPORT(relocate_new_kernel_size) | ||||||
|  | -	PTR		relocate_new_kernel_end - relocate_new_kernel | ||||||
|  | -	.size		relocate_new_kernel_size, PTRSIZE | ||||||
|  | +kexec_relocate_new_kernel_end: | ||||||
|  | +	EXPORT(kexec_relocate_new_kernel_end) | ||||||
| @@ -0,0 +1,80 @@ | |||||||
|  | From: Alexey Brodkin <abrodkin@synopsys.com> | ||||||
|  | Subject: openwrt: arc - add OWRTDTB section | ||||||
|  |  | ||||||
|  | This change allows OpenWRT to patch resulting kernel binary with | ||||||
|  | external .dtb. | ||||||
|  |  | ||||||
|  | That allows us to re-use exactky the same vmlinux on different boards | ||||||
|  | given its ARC core configurations match (at least cache line sizes etc). | ||||||
|  |  | ||||||
|  | ""patch-dtb" searches for ASCII "OWRTDTB:" strign and copies external | ||||||
|  | .dtb right after it, keeping the string in place. | ||||||
|  |  | ||||||
|  | Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com> | ||||||
|  | --- | ||||||
|  |  arch/arc/kernel/head.S        | 10 ++++++++++ | ||||||
|  |  arch/arc/kernel/setup.c       |  4 +++- | ||||||
|  |  arch/arc/kernel/vmlinux.lds.S | 13 +++++++++++++ | ||||||
|  |  3 files changed, 26 insertions(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/arch/arc/kernel/head.S | ||||||
|  | +++ b/arch/arc/kernel/head.S | ||||||
|  | @@ -49,6 +49,16 @@ | ||||||
|  |  1: | ||||||
|  |  .endm | ||||||
|  |   | ||||||
|  | +; Here "patch-dtb" will embed external .dtb | ||||||
|  | +; Note "patch-dtb" searches for ASCII "OWRTDTB:" string | ||||||
|  | +; and pastes .dtb right after it, hense the string precedes | ||||||
|  | +; __image_dtb symbol. | ||||||
|  | +	.section .owrt, "aw",@progbits | ||||||
|  | +	.ascii	"OWRTDTB:" | ||||||
|  | +ENTRY(__image_dtb) | ||||||
|  | +	.fill	0x4000 | ||||||
|  | +END(__image_dtb) | ||||||
|  | + | ||||||
|  |  	.section .init.text, "ax",@progbits | ||||||
|  |   | ||||||
|  |  ;---------------------------------------------------------------- | ||||||
|  | --- a/arch/arc/kernel/setup.c | ||||||
|  | +++ b/arch/arc/kernel/setup.c | ||||||
|  | @@ -421,6 +421,8 @@ static inline int is_kernel(unsigned lon | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +extern struct boot_param_header __image_dtb; | ||||||
|  | + | ||||||
|  |  void __init setup_arch(char **cmdline_p) | ||||||
|  |  { | ||||||
|  |  #ifdef CONFIG_ARC_UBOOT_SUPPORT | ||||||
|  | @@ -434,7 +436,7 @@ void __init setup_arch(char **cmdline_p) | ||||||
|  |  #endif | ||||||
|  |  	{ | ||||||
|  |  		/* No, so try the embedded one */ | ||||||
|  | -		machine_desc = setup_machine_fdt(__dtb_start); | ||||||
|  | +		machine_desc = setup_machine_fdt(&__image_dtb); | ||||||
|  |  		if (!machine_desc) | ||||||
|  |  			panic("Embedded DT invalid\n"); | ||||||
|  |   | ||||||
|  | --- a/arch/arc/kernel/vmlinux.lds.S | ||||||
|  | +++ b/arch/arc/kernel/vmlinux.lds.S | ||||||
|  | @@ -30,6 +30,19 @@ SECTIONS | ||||||
|  |   | ||||||
|  |  	. = CONFIG_LINUX_LINK_BASE; | ||||||
|  |   | ||||||
|  | +	/* | ||||||
|  | +	 * In OpenWRT we want to patch built binary embedding .dtb of choice. | ||||||
|  | +	 * This is implemented with "patch-dtb" utility which searches for | ||||||
|  | +	 * "OWRTDTB:" string in first 16k of image and if it is found | ||||||
|  | +	 * copies .dtb right after mentioned string. | ||||||
|  | +	 * | ||||||
|  | +	 * Note: "OWRTDTB:" won't be overwritten with .dtb, .dtb will follow it. | ||||||
|  | +	 */ | ||||||
|  | +	.owrt : { | ||||||
|  | +		*(.owrt) | ||||||
|  | +		. = ALIGN(PAGE_SIZE); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	_int_vec_base_lds = .; | ||||||
|  |  	.vector : { | ||||||
|  |  		*(.vector) | ||||||
| @@ -0,0 +1,24 @@ | |||||||
|  | From: Alexey Brodkin <abrodkin@synopsys.com> | ||||||
|  | Subject: arc: enable unaligned access in kernel mode | ||||||
|  |  | ||||||
|  | This enables misaligned access handling even in kernel mode. | ||||||
|  | Some wireless drivers (ath9k-htc and mt7601u) use misaligned accesses | ||||||
|  | here and there and to cope with that without fixing stuff in the drivers | ||||||
|  | we're just gracefully handling it on ARC. | ||||||
|  |  | ||||||
|  | Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com> | ||||||
|  | --- | ||||||
|  |  arch/arc/kernel/unaligned.c | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/arch/arc/kernel/unaligned.c | ||||||
|  | +++ b/arch/arc/kernel/unaligned.c | ||||||
|  | @@ -206,7 +206,7 @@ int misaligned_fixup(unsigned long addre | ||||||
|  |  	char buf[TASK_COMM_LEN]; | ||||||
|  |   | ||||||
|  |  	/* handle user mode only and only if enabled by sysadmin */ | ||||||
|  | -	if (!user_mode(regs) || !unaligned_enabled) | ||||||
|  | +	if (!unaligned_enabled) | ||||||
|  |  		return 1; | ||||||
|  |   | ||||||
|  |  	if (no_unaligned_warning) { | ||||||
| @@ -0,0 +1,32 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Tue, 5 Dec 2017 12:34:31 +0100 | ||||||
|  | Subject: [PATCH] MIPS: mm: remove mips_dma_mapping_error | ||||||
|  |  | ||||||
|  | dma_mapping_error() already checks if ops->mapping_error is a null | ||||||
|  | pointer | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/arch/mips/mm/dma-default.c | ||||||
|  | +++ b/arch/mips/mm/dma-default.c | ||||||
|  | @@ -373,11 +373,6 @@ static void mips_dma_sync_sg_for_device( | ||||||
|  |  	} | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | ||||||
|  | -{ | ||||||
|  | -	return 0; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  |  static int mips_dma_supported(struct device *dev, u64 mask) | ||||||
|  |  { | ||||||
|  |  	return plat_dma_supported(dev, mask); | ||||||
|  | @@ -406,7 +401,6 @@ static const struct dma_map_ops mips_def | ||||||
|  |  	.sync_single_for_device = mips_dma_sync_single_for_device, | ||||||
|  |  	.sync_sg_for_cpu = mips_dma_sync_sg_for_cpu, | ||||||
|  |  	.sync_sg_for_device = mips_dma_sync_sg_for_device, | ||||||
|  | -	.mapping_error = mips_dma_mapping_error, | ||||||
|  |  	.dma_supported = mips_dma_supported | ||||||
|  |  }; | ||||||
|  |   | ||||||
| @@ -0,0 +1,140 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Tue, 5 Dec 2017 12:46:01 +0100 | ||||||
|  | Subject: [PATCH] MIPS: mm: remove no-op dma_map_ops where possible | ||||||
|  |  | ||||||
|  | If no post-DMA flush is required, and the platform does not provide | ||||||
|  | plat_unmap_dma_mem(), there is no need to include unmap or sync_for_cpu | ||||||
|  | ops. | ||||||
|  |  | ||||||
|  | With this patch they are compiled out to improve icache footprint | ||||||
|  | on devices that handle lots of DMA traffic (especially network routers). | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/arch/mips/Kconfig | ||||||
|  | +++ b/arch/mips/Kconfig | ||||||
|  | @@ -220,6 +220,7 @@ config BMIPS_GENERIC | ||||||
|  |  	select BRCMSTB_L2_IRQ | ||||||
|  |  	select IRQ_MIPS_CPU | ||||||
|  |  	select DMA_NONCOHERENT | ||||||
|  | +	select DMA_UNMAP_POST_FLUSH | ||||||
|  |  	select SYS_SUPPORTS_32BIT_KERNEL | ||||||
|  |  	select SYS_SUPPORTS_LITTLE_ENDIAN | ||||||
|  |  	select SYS_SUPPORTS_BIG_ENDIAN | ||||||
|  | @@ -345,6 +346,7 @@ config MACH_JAZZ | ||||||
|  |  	select CSRC_R4K | ||||||
|  |  	select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN | ||||||
|  |  	select GENERIC_ISA_DMA | ||||||
|  | +	select DMA_UNMAP_POST_FLUSH | ||||||
|  |  	select HAVE_PCSPKR_PLATFORM | ||||||
|  |  	select IRQ_MIPS_CPU | ||||||
|  |  	select I8253 | ||||||
|  | @@ -1127,6 +1129,9 @@ config DMA_NONCOHERENT | ||||||
|  |  	bool | ||||||
|  |  	select NEED_DMA_MAP_STATE | ||||||
|  |   | ||||||
|  | +config DMA_UNMAP_POST_FLUSH | ||||||
|  | +	bool | ||||||
|  | + | ||||||
|  |  config NEED_DMA_MAP_STATE | ||||||
|  |  	bool | ||||||
|  |   | ||||||
|  | @@ -1651,6 +1656,7 @@ config CPU_R10000 | ||||||
|  |  	select CPU_SUPPORTS_64BIT_KERNEL | ||||||
|  |  	select CPU_SUPPORTS_HIGHMEM | ||||||
|  |  	select CPU_SUPPORTS_HUGEPAGES | ||||||
|  | +	select DMA_UNMAP_POST_FLUSH | ||||||
|  |  	help | ||||||
|  |  	  MIPS Technologies R10000-series processors. | ||||||
|  |   | ||||||
|  | @@ -1899,9 +1905,11 @@ config SYS_HAS_CPU_MIPS32_R3_5 | ||||||
|  |  	bool | ||||||
|  |   | ||||||
|  |  config SYS_HAS_CPU_MIPS32_R5 | ||||||
|  | +	select DMA_UNMAP_POST_FLUSH | ||||||
|  |  	bool | ||||||
|  |   | ||||||
|  |  config SYS_HAS_CPU_MIPS32_R6 | ||||||
|  | +	select DMA_UNMAP_POST_FLUSH | ||||||
|  |  	bool | ||||||
|  |   | ||||||
|  |  config SYS_HAS_CPU_MIPS64_R1 | ||||||
|  | @@ -1911,6 +1919,7 @@ config SYS_HAS_CPU_MIPS64_R2 | ||||||
|  |  	bool | ||||||
|  |   | ||||||
|  |  config SYS_HAS_CPU_MIPS64_R6 | ||||||
|  | +	select DMA_UNMAP_POST_FLUSH | ||||||
|  |  	bool | ||||||
|  |   | ||||||
|  |  config SYS_HAS_CPU_R3000 | ||||||
|  | --- a/arch/mips/mm/dma-default.c | ||||||
|  | +++ b/arch/mips/mm/dma-default.c | ||||||
|  | @@ -267,8 +267,9 @@ static inline void __dma_sync(struct pag | ||||||
|  |  	} while (left); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, | ||||||
|  | -	size_t size, enum dma_data_direction direction, unsigned long attrs) | ||||||
|  | +static void __maybe_unused | ||||||
|  | +mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, | ||||||
|  | +		    enum dma_data_direction direction, unsigned long attrs) | ||||||
|  |  { | ||||||
|  |  	if (cpu_needs_post_dma_flush(dev) && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) | ||||||
|  |  		__dma_sync(dma_addr_to_page(dev, dma_addr), | ||||||
|  | @@ -308,9 +309,10 @@ static dma_addr_t mips_dma_map_page(stru | ||||||
|  |  	return plat_map_dma_mem_page(dev, page) + offset; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, | ||||||
|  | -	int nhwentries, enum dma_data_direction direction, | ||||||
|  | -	unsigned long attrs) | ||||||
|  | +static void __maybe_unused | ||||||
|  | +mips_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, | ||||||
|  | +		  int nhwentries, enum dma_data_direction direction, | ||||||
|  | +		  unsigned long attrs) | ||||||
|  |  { | ||||||
|  |  	int i; | ||||||
|  |  	struct scatterlist *sg; | ||||||
|  | @@ -325,8 +327,9 @@ static void mips_dma_unmap_sg(struct dev | ||||||
|  |  	} | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static void mips_dma_sync_single_for_cpu(struct device *dev, | ||||||
|  | -	dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) | ||||||
|  | +static void __maybe_unused | ||||||
|  | +mips_dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, | ||||||
|  | +			     size_t size, enum dma_data_direction direction) | ||||||
|  |  { | ||||||
|  |  	if (cpu_needs_post_dma_flush(dev)) | ||||||
|  |  		__dma_sync(dma_addr_to_page(dev, dma_handle), | ||||||
|  | @@ -342,9 +345,9 @@ static void mips_dma_sync_single_for_dev | ||||||
|  |  			   dma_handle & ~PAGE_MASK, size, direction); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static void mips_dma_sync_sg_for_cpu(struct device *dev, | ||||||
|  | -	struct scatterlist *sglist, int nelems, | ||||||
|  | -	enum dma_data_direction direction) | ||||||
|  | +static void __maybe_unused | ||||||
|  | +mips_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist, | ||||||
|  | +			 int nelems, enum dma_data_direction direction) | ||||||
|  |  { | ||||||
|  |  	int i; | ||||||
|  |  	struct scatterlist *sg; | ||||||
|  | @@ -394,12 +397,14 @@ static const struct dma_map_ops mips_def | ||||||
|  |  	.free = mips_dma_free_coherent, | ||||||
|  |  	.mmap = mips_dma_mmap, | ||||||
|  |  	.map_page = mips_dma_map_page, | ||||||
|  | -	.unmap_page = mips_dma_unmap_page, | ||||||
|  |  	.map_sg = mips_dma_map_sg, | ||||||
|  | +#ifdef CONFIG_DMA_UNMAP_POST_FLUSH | ||||||
|  | +	.unmap_page = mips_dma_unmap_page, | ||||||
|  |  	.unmap_sg = mips_dma_unmap_sg, | ||||||
|  |  	.sync_single_for_cpu = mips_dma_sync_single_for_cpu, | ||||||
|  | -	.sync_single_for_device = mips_dma_sync_single_for_device, | ||||||
|  |  	.sync_sg_for_cpu = mips_dma_sync_sg_for_cpu, | ||||||
|  | +#endif | ||||||
|  | +	.sync_single_for_device = mips_dma_sync_single_for_device, | ||||||
|  |  	.sync_sg_for_device = mips_dma_sync_sg_for_device, | ||||||
|  |  	.dma_supported = mips_dma_supported | ||||||
|  |  }; | ||||||
| @@ -0,0 +1,123 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: make rootfs split/detection more generic - patch can be moved to generic-2.6 after testing on other platforms | ||||||
|  |  | ||||||
|  | lede-commit: 328e660b31f0937d52c5ae3d6e7029409918a9df | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/Kconfig            | 17 +++++++++++++++++ | ||||||
|  |  drivers/mtd/mtdpart.c          | 35 +++++++++++++++++++++++++++++++++++ | ||||||
|  |  include/linux/mtd/partitions.h |  2 ++ | ||||||
|  |  3 files changed, 54 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/Kconfig | ||||||
|  | +++ b/drivers/mtd/Kconfig | ||||||
|  | @@ -12,6 +12,23 @@ menuconfig MTD | ||||||
|  |   | ||||||
|  |  if MTD | ||||||
|  |   | ||||||
|  | +menu "OpenWrt specific MTD options" | ||||||
|  | + | ||||||
|  | +config MTD_ROOTFS_ROOT_DEV | ||||||
|  | +	bool "Automatically set 'rootfs' partition to be root filesystem" | ||||||
|  | +	default y | ||||||
|  | + | ||||||
|  | +config MTD_SPLIT_FIRMWARE | ||||||
|  | +	bool "Automatically split firmware partition for kernel+rootfs" | ||||||
|  | +	default y | ||||||
|  | + | ||||||
|  | +config MTD_SPLIT_FIRMWARE_NAME | ||||||
|  | +	string "Firmware partition name" | ||||||
|  | +	depends on MTD_SPLIT_FIRMWARE | ||||||
|  | +	default "firmware" | ||||||
|  | + | ||||||
|  | +endmenu | ||||||
|  | + | ||||||
|  |  config MTD_TESTS | ||||||
|  |  	tristate "MTD tests support (DANGEROUS)" | ||||||
|  |  	depends on m | ||||||
|  | --- a/drivers/mtd/mtdpart.c | ||||||
|  | +++ b/drivers/mtd/mtdpart.c | ||||||
|  | @@ -29,10 +29,12 @@ | ||||||
|  |  #include <linux/kmod.h> | ||||||
|  |  #include <linux/mtd/mtd.h> | ||||||
|  |  #include <linux/mtd/partitions.h> | ||||||
|  | +#include <linux/magic.h> | ||||||
|  |  #include <linux/of.h> | ||||||
|  |  #include <linux/err.h> | ||||||
|  |   | ||||||
|  |  #include "mtdcore.h" | ||||||
|  | +#include "mtdsplit/mtdsplit.h" | ||||||
|  |   | ||||||
|  |  /* Our partition linked list */ | ||||||
|  |  static LIST_HEAD(mtd_partitions); | ||||||
|  | @@ -52,6 +54,8 @@ struct mtd_part { | ||||||
|  |  	struct list_head list; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +static void mtd_partition_split(struct mtd_info *master, struct mtd_part *part); | ||||||
|  | + | ||||||
|  |  /* | ||||||
|  |   * Given a pointer to the MTD object in the mtd_part structure, we can retrieve | ||||||
|  |   * the pointer to that structure. | ||||||
|  | @@ -686,6 +690,7 @@ int mtd_add_partition(struct mtd_info *p | ||||||
|  |  	mutex_unlock(&mtd_partitions_mutex); | ||||||
|  |   | ||||||
|  |  	add_mtd_device(&new->mtd); | ||||||
|  | +	mtd_partition_split(parent, new); | ||||||
|  |   | ||||||
|  |  	mtd_add_partition_attrs(new); | ||||||
|  |   | ||||||
|  | @@ -764,6 +769,35 @@ int mtd_del_partition(struct mtd_info *m | ||||||
|  |  } | ||||||
|  |  EXPORT_SYMBOL_GPL(mtd_del_partition); | ||||||
|  |   | ||||||
|  | +#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME | ||||||
|  | +#define SPLIT_FIRMWARE_NAME	CONFIG_MTD_SPLIT_FIRMWARE_NAME | ||||||
|  | +#else | ||||||
|  | +#define SPLIT_FIRMWARE_NAME	"unused" | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  | +static void split_firmware(struct mtd_info *master, struct mtd_part *part) | ||||||
|  | +{ | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +void __weak arch_split_mtd_part(struct mtd_info *master, const char *name, | ||||||
|  | +                                int offset, int size) | ||||||
|  | +{ | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void mtd_partition_split(struct mtd_info *master, struct mtd_part *part) | ||||||
|  | +{ | ||||||
|  | +	static int rootfs_found = 0; | ||||||
|  | + | ||||||
|  | +	if (rootfs_found) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	if (!strcmp(part->mtd.name, SPLIT_FIRMWARE_NAME) && | ||||||
|  | +	    IS_ENABLED(CONFIG_MTD_SPLIT_FIRMWARE)) | ||||||
|  | +		split_firmware(master, part); | ||||||
|  | + | ||||||
|  | +	arch_split_mtd_part(master, part->mtd.name, part->offset, | ||||||
|  | +			    part->mtd.size); | ||||||
|  | +} | ||||||
|  |  /* | ||||||
|  |   * This function, given a master MTD object and a partition table, creates | ||||||
|  |   * and registers slave MTD objects which are bound to the master according to | ||||||
|  | @@ -795,6 +829,7 @@ int add_mtd_partitions(struct mtd_info * | ||||||
|  |  		mutex_unlock(&mtd_partitions_mutex); | ||||||
|  |   | ||||||
|  |  		add_mtd_device(&slave->mtd); | ||||||
|  | +		mtd_partition_split(master, slave); | ||||||
|  |  		mtd_add_partition_attrs(slave); | ||||||
|  |  		if (parts[i].types) | ||||||
|  |  			mtd_parse_part(slave, parts[i].types); | ||||||
|  | --- a/include/linux/mtd/partitions.h | ||||||
|  | +++ b/include/linux/mtd/partitions.h | ||||||
|  | @@ -109,5 +109,7 @@ int mtd_add_partition(struct mtd_info *m | ||||||
|  |  		      long long offset, long long length); | ||||||
|  |  int mtd_del_partition(struct mtd_info *master, int partno); | ||||||
|  |  uint64_t mtd_get_device_size(const struct mtd_info *mtd); | ||||||
|  | +extern void __weak arch_split_mtd_part(struct mtd_info *master, | ||||||
|  | +				       const char *name, int offset, int size); | ||||||
|  |   | ||||||
|  |  #endif | ||||||
| @@ -0,0 +1,110 @@ | |||||||
|  | From: Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | Subject: mtd: add support for different partition parser types | ||||||
|  |  | ||||||
|  | Signed-off-by: Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/mtdpart.c          |   56 ++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  include/linux/mtd/partitions.h |   11 ++++++++ | ||||||
|  |  2 files changed, 67 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/mtdpart.c | ||||||
|  | +++ b/drivers/mtd/mtdpart.c | ||||||
|  | @@ -1034,6 +1034,62 @@ void mtd_part_parser_cleanup(struct mtd_ | ||||||
|  |  	} | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static struct mtd_part_parser * | ||||||
|  | +get_partition_parser_by_type(enum mtd_parser_type type, | ||||||
|  | +			     struct mtd_part_parser *start) | ||||||
|  | +{ | ||||||
|  | +	struct mtd_part_parser *p, *ret = NULL; | ||||||
|  | + | ||||||
|  | +	spin_lock(&part_parser_lock); | ||||||
|  | + | ||||||
|  | +	p = list_prepare_entry(start, &part_parsers, list); | ||||||
|  | +	if (start) | ||||||
|  | +		mtd_part_parser_put(start); | ||||||
|  | + | ||||||
|  | +	list_for_each_entry_continue(p, &part_parsers, list) { | ||||||
|  | +		if (p->type == type && try_module_get(p->owner)) { | ||||||
|  | +			ret = p; | ||||||
|  | +			break; | ||||||
|  | +		} | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	spin_unlock(&part_parser_lock); | ||||||
|  | + | ||||||
|  | +	return ret; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +int parse_mtd_partitions_by_type(struct mtd_info *master, | ||||||
|  | +				 enum mtd_parser_type type, | ||||||
|  | +				 const struct mtd_partition **pparts, | ||||||
|  | +				 struct mtd_part_parser_data *data) | ||||||
|  | +{ | ||||||
|  | +	struct mtd_part_parser *prev = NULL; | ||||||
|  | +	int ret = 0; | ||||||
|  | + | ||||||
|  | +	while (1) { | ||||||
|  | +		struct mtd_part_parser *parser; | ||||||
|  | + | ||||||
|  | +		parser = get_partition_parser_by_type(type, prev); | ||||||
|  | +		if (!parser) | ||||||
|  | +			break; | ||||||
|  | + | ||||||
|  | +		ret = (*parser->parse_fn)(master, pparts, data); | ||||||
|  | + | ||||||
|  | +		if (ret > 0) { | ||||||
|  | +			mtd_part_parser_put(parser); | ||||||
|  | +			printk(KERN_NOTICE | ||||||
|  | +			       "%d %s partitions found on MTD device %s\n", | ||||||
|  | +			       ret, parser->name, master->name); | ||||||
|  | +			break; | ||||||
|  | +		} | ||||||
|  | + | ||||||
|  | +		prev = parser; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return ret; | ||||||
|  | +} | ||||||
|  | +EXPORT_SYMBOL_GPL(parse_mtd_partitions_by_type); | ||||||
|  | + | ||||||
|  |  int mtd_is_partition(const struct mtd_info *mtd) | ||||||
|  |  { | ||||||
|  |  	struct mtd_part *part; | ||||||
|  | --- a/include/linux/mtd/partitions.h | ||||||
|  | +++ b/include/linux/mtd/partitions.h | ||||||
|  | @@ -68,11 +68,14 @@ struct mtd_part_parser_data { | ||||||
|  |  	unsigned long origin; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | - | ||||||
|  |  /* | ||||||
|  |   * Functions dealing with the various ways of partitioning the space | ||||||
|  |   */ | ||||||
|  |   | ||||||
|  | +enum mtd_parser_type { | ||||||
|  | +	MTD_PARSER_TYPE_DEVICE = 0, | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  |  struct mtd_part_parser { | ||||||
|  |  	struct list_head list; | ||||||
|  |  	struct module *owner; | ||||||
|  | @@ -80,6 +83,7 @@ struct mtd_part_parser { | ||||||
|  |  	int (*parse_fn)(struct mtd_info *, const struct mtd_partition **, | ||||||
|  |  			struct mtd_part_parser_data *); | ||||||
|  |  	void (*cleanup)(const struct mtd_partition *pparts, int nr_parts); | ||||||
|  | +	enum mtd_parser_type type; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  /* Container for passing around a set of parsed partitions */ | ||||||
|  | @@ -112,4 +116,9 @@ uint64_t mtd_get_device_size(const struc | ||||||
|  |  extern void __weak arch_split_mtd_part(struct mtd_info *master, | ||||||
|  |  				       const char *name, int offset, int size); | ||||||
|  |   | ||||||
|  | +int parse_mtd_partitions_by_type(struct mtd_info *master, | ||||||
|  | +				 enum mtd_parser_type type, | ||||||
|  | +				 const struct mtd_partition **pparts, | ||||||
|  | +				 struct mtd_part_parser_data *data); | ||||||
|  | + | ||||||
|  |  #endif | ||||||
| @@ -0,0 +1,81 @@ | |||||||
|  | From: Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | Subject: kernel/3.10: allow to use partition parsers for rootfs and firmware split | ||||||
|  |  | ||||||
|  | lede-commit: 3b71cd94bc9517bc25267dccb393b07d4b54564e | ||||||
|  | Signed-off-by: Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/mtdpart.c          | 37 +++++++++++++++++++++++++++++++++++++ | ||||||
|  |  include/linux/mtd/partitions.h |  2 ++ | ||||||
|  |  2 files changed, 39 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/mtdpart.c | ||||||
|  | +++ b/drivers/mtd/mtdpart.c | ||||||
|  | @@ -769,6 +769,36 @@ int mtd_del_partition(struct mtd_info *m | ||||||
|  |  } | ||||||
|  |  EXPORT_SYMBOL_GPL(mtd_del_partition); | ||||||
|  |   | ||||||
|  | +static int | ||||||
|  | +run_parsers_by_type(struct mtd_part *slave, enum mtd_parser_type type) | ||||||
|  | +{ | ||||||
|  | +	struct mtd_partition *parts; | ||||||
|  | +	int nr_parts; | ||||||
|  | +	int i; | ||||||
|  | + | ||||||
|  | +	nr_parts = parse_mtd_partitions_by_type(&slave->mtd, type, (const struct mtd_partition **)&parts, | ||||||
|  | +						NULL); | ||||||
|  | +	if (nr_parts <= 0) | ||||||
|  | +		return nr_parts; | ||||||
|  | + | ||||||
|  | +	if (WARN_ON(!parts)) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  | +	for (i = 0; i < nr_parts; i++) { | ||||||
|  | +		/* adjust partition offsets */ | ||||||
|  | +		parts[i].offset += slave->offset; | ||||||
|  | + | ||||||
|  | +		mtd_add_partition(slave->parent, | ||||||
|  | +				  parts[i].name, | ||||||
|  | +				  parts[i].offset, | ||||||
|  | +				  parts[i].size); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	kfree(parts); | ||||||
|  | + | ||||||
|  | +	return nr_parts; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  #ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME | ||||||
|  |  #define SPLIT_FIRMWARE_NAME	CONFIG_MTD_SPLIT_FIRMWARE_NAME | ||||||
|  |  #else | ||||||
|  | @@ -777,6 +807,7 @@ EXPORT_SYMBOL_GPL(mtd_del_partition); | ||||||
|  |   | ||||||
|  |  static void split_firmware(struct mtd_info *master, struct mtd_part *part) | ||||||
|  |  { | ||||||
|  | +	run_parsers_by_type(part, MTD_PARSER_TYPE_FIRMWARE); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  void __weak arch_split_mtd_part(struct mtd_info *master, const char *name, | ||||||
|  | @@ -791,6 +822,12 @@ static void mtd_partition_split(struct m | ||||||
|  |  	if (rootfs_found) | ||||||
|  |  		return; | ||||||
|  |   | ||||||
|  | +	if (!strcmp(part->mtd.name, "rootfs")) { | ||||||
|  | +		run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS); | ||||||
|  | + | ||||||
|  | +		rootfs_found = 1; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	if (!strcmp(part->mtd.name, SPLIT_FIRMWARE_NAME) && | ||||||
|  |  	    IS_ENABLED(CONFIG_MTD_SPLIT_FIRMWARE)) | ||||||
|  |  		split_firmware(master, part); | ||||||
|  | --- a/include/linux/mtd/partitions.h | ||||||
|  | +++ b/include/linux/mtd/partitions.h | ||||||
|  | @@ -74,6 +74,8 @@ struct mtd_part_parser_data { | ||||||
|  |   | ||||||
|  |  enum mtd_parser_type { | ||||||
|  |  	MTD_PARSER_TYPE_DEVICE = 0, | ||||||
|  | +	MTD_PARSER_TYPE_ROOTFS, | ||||||
|  | +	MTD_PARSER_TYPE_FIRMWARE, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  struct mtd_part_parser { | ||||||
| @@ -0,0 +1,32 @@ | |||||||
|  | From: Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | Subject: [PATCH] kernel/3.10: move squashfs check from rootfs split code into a separate file | ||||||
|  |  | ||||||
|  | lede-commit: d89bea92b31b4e157a0fa438e75370f089f73427 | ||||||
|  | Signed-off-by: Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/Kconfig  | 2 ++ | ||||||
|  |  drivers/mtd/Makefile | 2 ++ | ||||||
|  |  2 files changed, 4 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/Kconfig | ||||||
|  | +++ b/drivers/mtd/Kconfig | ||||||
|  | @@ -27,6 +27,8 @@ config MTD_SPLIT_FIRMWARE_NAME | ||||||
|  |  	depends on MTD_SPLIT_FIRMWARE | ||||||
|  |  	default "firmware" | ||||||
|  |   | ||||||
|  | +source "drivers/mtd/mtdsplit/Kconfig" | ||||||
|  | + | ||||||
|  |  endmenu | ||||||
|  |   | ||||||
|  |  config MTD_TESTS | ||||||
|  | --- a/drivers/mtd/Makefile | ||||||
|  | +++ b/drivers/mtd/Makefile | ||||||
|  | @@ -7,6 +7,8 @@ | ||||||
|  |  obj-$(CONFIG_MTD)		+= mtd.o | ||||||
|  |  mtd-y				:= mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o mtdchar.o | ||||||
|  |   | ||||||
|  | +obj-$(CONFIG_MTD_SPLIT)		+= mtdsplit/ | ||||||
|  | + | ||||||
|  |  obj-$(CONFIG_MTD_OF_PARTS)	+= ofpart.o | ||||||
|  |  obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o | ||||||
|  |  obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o | ||||||
| @@ -0,0 +1,94 @@ | |||||||
|  | From: Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | Subject: kernel/3.10: add separate rootfs partition parser | ||||||
|  |  | ||||||
|  | lede-commit: daec7ad7688415156e2730e401503d09bd3acf91 | ||||||
|  | Signed-off-by: Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/mtdpart.c          | 29 +++++++++++++++++++++++++++++ | ||||||
|  |  include/linux/mtd/mtd.h        | 18 ++++++++++++++++++ | ||||||
|  |  include/linux/mtd/partitions.h |  2 ++ | ||||||
|  |  3 files changed, 49 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/mtdpart.c | ||||||
|  | +++ b/drivers/mtd/mtdpart.c | ||||||
|  | @@ -799,6 +799,17 @@ run_parsers_by_type(struct mtd_part *sla | ||||||
|  |  	return nr_parts; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static inline unsigned long | ||||||
|  | +mtd_pad_erasesize(struct mtd_info *mtd, int offset, int len) | ||||||
|  | +{ | ||||||
|  | +	unsigned long mask = mtd->erasesize - 1; | ||||||
|  | + | ||||||
|  | +	len += offset & mask; | ||||||
|  | +	len = (len + mask) & ~mask; | ||||||
|  | +	len -= offset & mask; | ||||||
|  | +	return len; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  #ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME | ||||||
|  |  #define SPLIT_FIRMWARE_NAME	CONFIG_MTD_SPLIT_FIRMWARE_NAME | ||||||
|  |  #else | ||||||
|  | @@ -1144,6 +1155,24 @@ int mtd_is_partition(const struct mtd_in | ||||||
|  |  } | ||||||
|  |  EXPORT_SYMBOL_GPL(mtd_is_partition); | ||||||
|  |   | ||||||
|  | +struct mtd_info *mtdpart_get_master(const struct mtd_info *mtd) | ||||||
|  | +{ | ||||||
|  | +	if (!mtd_is_partition(mtd)) | ||||||
|  | +		return (struct mtd_info *)mtd; | ||||||
|  | + | ||||||
|  | +	return mtd_to_part(mtd)->parent; | ||||||
|  | +} | ||||||
|  | +EXPORT_SYMBOL_GPL(mtdpart_get_master); | ||||||
|  | + | ||||||
|  | +uint64_t mtdpart_get_offset(const struct mtd_info *mtd) | ||||||
|  | +{ | ||||||
|  | +	if (!mtd_is_partition(mtd)) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  | +	return mtd_to_part(mtd)->offset; | ||||||
|  | +} | ||||||
|  | +EXPORT_SYMBOL_GPL(mtdpart_get_offset); | ||||||
|  | + | ||||||
|  |  /* Returns the size of the entire flash chip */ | ||||||
|  |  uint64_t mtd_get_device_size(const struct mtd_info *mtd) | ||||||
|  |  { | ||||||
|  | --- a/include/linux/mtd/mtd.h | ||||||
|  | +++ b/include/linux/mtd/mtd.h | ||||||
|  | @@ -493,6 +493,24 @@ static inline uint32_t mtd_mod_by_eb(uin | ||||||
|  |  	return do_div(sz, mtd->erasesize); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static inline uint64_t mtd_roundup_to_eb(uint64_t sz, struct mtd_info *mtd) | ||||||
|  | +{ | ||||||
|  | +	if (mtd_mod_by_eb(sz, mtd) == 0) | ||||||
|  | +		return sz; | ||||||
|  | + | ||||||
|  | +	/* Round up to next erase block */ | ||||||
|  | +	return (mtd_div_by_eb(sz, mtd) + 1) * mtd->erasesize; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static inline uint64_t mtd_rounddown_to_eb(uint64_t sz, struct mtd_info *mtd) | ||||||
|  | +{ | ||||||
|  | +	if (mtd_mod_by_eb(sz, mtd) == 0) | ||||||
|  | +		return sz; | ||||||
|  | + | ||||||
|  | +	/* Round down to the start of the current erase block */ | ||||||
|  | +	return (mtd_div_by_eb(sz, mtd)) * mtd->erasesize; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd) | ||||||
|  |  { | ||||||
|  |  	if (mtd->writesize_shift) | ||||||
|  | --- a/include/linux/mtd/partitions.h | ||||||
|  | +++ b/include/linux/mtd/partitions.h | ||||||
|  | @@ -114,6 +114,8 @@ int mtd_is_partition(const struct mtd_in | ||||||
|  |  int mtd_add_partition(struct mtd_info *master, const char *name, | ||||||
|  |  		      long long offset, long long length); | ||||||
|  |  int mtd_del_partition(struct mtd_info *master, int partno); | ||||||
|  | +struct mtd_info *mtdpart_get_master(const struct mtd_info *mtd); | ||||||
|  | +uint64_t mtdpart_get_offset(const struct mtd_info *mtd); | ||||||
|  |  uint64_t mtd_get_device_size(const struct mtd_info *mtd); | ||||||
|  |  extern void __weak arch_split_mtd_part(struct mtd_info *master, | ||||||
|  |  				       const char *name, int offset, int size); | ||||||
| @@ -0,0 +1,154 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: mtd: implement write support for partitions covering only a part of an eraseblock (buffer data that would otherwise be erased) | ||||||
|  |  | ||||||
|  | lede-commit: 87a8e8ac1067f58ba831c4aae443f3655c31cd80 | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/mtdpart.c   | 90 ++++++++++++++++++++++++++++++++++++++++++++----- | ||||||
|  |  include/linux/mtd/mtd.h |  4 +++ | ||||||
|  |  2 files changed, 85 insertions(+), 9 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/mtdpart.c | ||||||
|  | +++ b/drivers/mtd/mtdpart.c | ||||||
|  | @@ -36,6 +36,8 @@ | ||||||
|  |  #include "mtdcore.h" | ||||||
|  |  #include "mtdsplit/mtdsplit.h" | ||||||
|  |   | ||||||
|  | +#define MTD_ERASE_PARTIAL	0x8000 /* partition only covers parts of an erase block */ | ||||||
|  | + | ||||||
|  |  /* Our partition linked list */ | ||||||
|  |  static LIST_HEAD(mtd_partitions); | ||||||
|  |  static DEFINE_MUTEX(mtd_partitions_mutex); | ||||||
|  | @@ -241,13 +243,61 @@ static int part_erase(struct mtd_info *m | ||||||
|  |  	struct mtd_part *part = mtd_to_part(mtd); | ||||||
|  |  	int ret; | ||||||
|  |   | ||||||
|  | + | ||||||
|  | +	instr->partial_start = false; | ||||||
|  | +	if (mtd->flags & MTD_ERASE_PARTIAL) { | ||||||
|  | +		size_t readlen = 0; | ||||||
|  | +		u64 mtd_ofs; | ||||||
|  | + | ||||||
|  | +		instr->erase_buf = kmalloc(part->parent->erasesize, GFP_ATOMIC); | ||||||
|  | +		if (!instr->erase_buf) | ||||||
|  | +			return -ENOMEM; | ||||||
|  | + | ||||||
|  | +		mtd_ofs = part->offset + instr->addr; | ||||||
|  | +		instr->erase_buf_ofs = do_div(mtd_ofs, part->parent->erasesize); | ||||||
|  | + | ||||||
|  | +		if (instr->erase_buf_ofs > 0) { | ||||||
|  | +			instr->addr -= instr->erase_buf_ofs; | ||||||
|  | +			ret = mtd_read(part->parent, | ||||||
|  | +				instr->addr + part->offset, | ||||||
|  | +				part->parent->erasesize, | ||||||
|  | +				&readlen, instr->erase_buf); | ||||||
|  | + | ||||||
|  | +			instr->len += instr->erase_buf_ofs; | ||||||
|  | +			instr->partial_start = true; | ||||||
|  | +		} else { | ||||||
|  | +			mtd_ofs = part->offset + part->mtd.size; | ||||||
|  | +			instr->erase_buf_ofs = part->parent->erasesize - | ||||||
|  | +				do_div(mtd_ofs, part->parent->erasesize); | ||||||
|  | + | ||||||
|  | +			if (instr->erase_buf_ofs > 0) { | ||||||
|  | +				instr->len += instr->erase_buf_ofs; | ||||||
|  | +				ret = mtd_read(part->parent, | ||||||
|  | +					part->offset + instr->addr + | ||||||
|  | +					instr->len - part->parent->erasesize, | ||||||
|  | +					part->parent->erasesize, &readlen, | ||||||
|  | +					instr->erase_buf); | ||||||
|  | +			} else { | ||||||
|  | +				ret = 0; | ||||||
|  | +			} | ||||||
|  | +		} | ||||||
|  | +		if (ret < 0) { | ||||||
|  | +			kfree(instr->erase_buf); | ||||||
|  | +			return ret; | ||||||
|  | +		} | ||||||
|  | + | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	instr->addr += part->offset; | ||||||
|  |  	ret = part->parent->_erase(part->parent, instr); | ||||||
|  |  	if (ret) { | ||||||
|  |  		if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) | ||||||
|  |  			instr->fail_addr -= part->offset; | ||||||
|  |  		instr->addr -= part->offset; | ||||||
|  | +		if (mtd->flags & MTD_ERASE_PARTIAL) | ||||||
|  | +			kfree(instr->erase_buf); | ||||||
|  |  	} | ||||||
|  | + | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -255,6 +305,25 @@ void mtd_erase_callback(struct erase_inf | ||||||
|  |  { | ||||||
|  |  	if (instr->mtd->_erase == part_erase) { | ||||||
|  |  		struct mtd_part *part = mtd_to_part(instr->mtd); | ||||||
|  | +		size_t wrlen = 0; | ||||||
|  | + | ||||||
|  | +		if (instr->mtd->flags & MTD_ERASE_PARTIAL) { | ||||||
|  | +			if (instr->partial_start) { | ||||||
|  | +				part->parent->_write(part->parent, | ||||||
|  | +					instr->addr, instr->erase_buf_ofs, | ||||||
|  | +					&wrlen, instr->erase_buf); | ||||||
|  | +				instr->addr += instr->erase_buf_ofs; | ||||||
|  | +			} else { | ||||||
|  | +				instr->len -= instr->erase_buf_ofs; | ||||||
|  | +				part->parent->_write(part->parent, | ||||||
|  | +					instr->addr + instr->len, | ||||||
|  | +					instr->erase_buf_ofs, &wrlen, | ||||||
|  | +					instr->erase_buf + | ||||||
|  | +					part->parent->erasesize - | ||||||
|  | +					instr->erase_buf_ofs); | ||||||
|  | +			} | ||||||
|  | +			kfree(instr->erase_buf); | ||||||
|  | +		} | ||||||
|  |   | ||||||
|  |  		if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) | ||||||
|  |  			instr->fail_addr -= part->offset; | ||||||
|  | @@ -598,19 +667,22 @@ static struct mtd_part *allocate_partiti | ||||||
|  |  	remainder = do_div(tmp, wr_alignment); | ||||||
|  |  	if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) { | ||||||
|  |  		/* Doesn't start on a boundary of major erase size */ | ||||||
|  | -		/* FIXME: Let it be writable if it is on a boundary of | ||||||
|  | -		 * _minor_ erase size though */ | ||||||
|  | -		slave->mtd.flags &= ~MTD_WRITEABLE; | ||||||
|  | -		printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase/write block boundary -- force read-only\n", | ||||||
|  | -			part->name); | ||||||
|  | +		slave->mtd.flags |= MTD_ERASE_PARTIAL; | ||||||
|  | +		if (((u32)slave->mtd.size) > parent->erasesize) | ||||||
|  | +			slave->mtd.flags &= ~MTD_WRITEABLE; | ||||||
|  | +		else | ||||||
|  | +			slave->mtd.erasesize = slave->mtd.size; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	tmp = slave->mtd.size; | ||||||
|  | +	tmp = slave->offset + slave->mtd.size; | ||||||
|  |  	remainder = do_div(tmp, wr_alignment); | ||||||
|  |  	if ((slave->mtd.flags & MTD_WRITEABLE) && remainder) { | ||||||
|  | -		slave->mtd.flags &= ~MTD_WRITEABLE; | ||||||
|  | -		printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase/write block -- force read-only\n", | ||||||
|  | -			part->name); | ||||||
|  | +		slave->mtd.flags |= MTD_ERASE_PARTIAL; | ||||||
|  | + | ||||||
|  | +		if ((u32)slave->mtd.size > parent->erasesize) | ||||||
|  | +			slave->mtd.flags &= ~MTD_WRITEABLE; | ||||||
|  | +		else | ||||||
|  | +			slave->mtd.erasesize = slave->mtd.size; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	mtd_set_ooblayout(&slave->mtd, &part_ooblayout_ops); | ||||||
|  | --- a/include/linux/mtd/mtd.h | ||||||
|  | +++ b/include/linux/mtd/mtd.h | ||||||
|  | @@ -56,6 +56,10 @@ struct erase_info { | ||||||
|  |  	u_long priv; | ||||||
|  |  	u_char state; | ||||||
|  |  	struct erase_info *next; | ||||||
|  | + | ||||||
|  | +	u8 *erase_buf; | ||||||
|  | +	u32 erase_buf_ofs; | ||||||
|  | +	bool partial_start; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  struct mtd_erase_region_info { | ||||||
| @@ -0,0 +1,40 @@ | |||||||
|  | From: Tim Harvey <tharvey@gateworks.com> | ||||||
|  | Subject: mtd: allow partial block unlock | ||||||
|  |  | ||||||
|  | This allows sysupgrade for devices such as the Gateworks Avila/Cambria | ||||||
|  | product families based on the ixp4xx using the redboot bootloader with | ||||||
|  | combined FIS directory and RedBoot config partitions on larger FLASH | ||||||
|  | devices with larger eraseblocks. | ||||||
|  |  | ||||||
|  | This second iteration of this patch addresses previous issues: | ||||||
|  | - whitespace breakage fixed | ||||||
|  | - unlock in all scenarios | ||||||
|  | - simplification and fix logic bug | ||||||
|  |  | ||||||
|  | [john@phrozen.org: this should be moved to the ixp4xx folder] | ||||||
|  |  | ||||||
|  | Signed-off-by: Tim Harvey <tharvey@gateworks.com> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/mtdpart.c | 11 ++++++++++- | ||||||
|  |  1 file changed, 10 insertions(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/mtdpart.c | ||||||
|  | +++ b/drivers/mtd/mtdpart.c | ||||||
|  | @@ -343,7 +343,16 @@ static int part_lock(struct mtd_info *mt | ||||||
|  |  static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | ||||||
|  |  { | ||||||
|  |  	struct mtd_part *part = mtd_to_part(mtd); | ||||||
|  | -	return part->parent->_unlock(part->parent, ofs + part->offset, len); | ||||||
|  | + | ||||||
|  | +	ofs += part->offset; | ||||||
|  | + | ||||||
|  | +	if (mtd->flags & MTD_ERASE_PARTIAL) { | ||||||
|  | +		/* round up len to next erasesize and round down offset to prev block */ | ||||||
|  | +		len = (mtd_div_by_eb(len, part->parent) + 1) * part->parent->erasesize; | ||||||
|  | +		ofs &= ~(part->parent->erasesize - 1); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return part->parent->_unlock(part->parent, ofs, len); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) | ||||||
| @@ -0,0 +1,41 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: add patch for including unpartitioned space in the rootfs partition for redboot devices (if applicable) | ||||||
|  |  | ||||||
|  | [john@phrozen.org: used by ixp and others] | ||||||
|  |  | ||||||
|  | lede-commit: 394918851f84e4d00fa16eb900e7700e95091f00 | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/redboot.c | 19 +++++++++++++------ | ||||||
|  |  1 file changed, 13 insertions(+), 6 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/redboot.c | ||||||
|  | +++ b/drivers/mtd/redboot.c | ||||||
|  | @@ -265,14 +265,21 @@ static int parse_redboot_partitions(stru | ||||||
|  |  #endif | ||||||
|  |  		names += strlen(names)+1; | ||||||
|  |   | ||||||
|  | -#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED | ||||||
|  |  		if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) { | ||||||
|  | -			i++; | ||||||
|  | -			parts[i].offset = parts[i-1].size + parts[i-1].offset; | ||||||
|  | -			parts[i].size = fl->next->img->flash_base - parts[i].offset; | ||||||
|  | -			parts[i].name = nullname; | ||||||
|  | -		} | ||||||
|  | +			if (!strcmp(parts[i].name, "rootfs")) { | ||||||
|  | +				parts[i].size = fl->next->img->flash_base; | ||||||
|  | +				parts[i].size &= ~(master->erasesize - 1); | ||||||
|  | +				parts[i].size -= parts[i].offset; | ||||||
|  | +#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED | ||||||
|  | +				nrparts--; | ||||||
|  | +			} else { | ||||||
|  | +				i++; | ||||||
|  | +				parts[i].offset = parts[i-1].size + parts[i-1].offset; | ||||||
|  | +				parts[i].size = fl->next->img->flash_base - parts[i].offset; | ||||||
|  | +				parts[i].name = nullname; | ||||||
|  |  #endif | ||||||
|  | +			} | ||||||
|  | +		} | ||||||
|  |  		tmp_fl = fl; | ||||||
|  |  		fl = fl->next; | ||||||
|  |  		kfree(tmp_fl); | ||||||
| @@ -0,0 +1,47 @@ | |||||||
|  | From: Florian Fainelli <f.fainelli@gmail.com> | ||||||
|  | Subject: Add myloader partition table parser | ||||||
|  |  | ||||||
|  | [john@phozen.org: shoud be upstreamable] | ||||||
|  |  | ||||||
|  | lede-commit: d8bf22859b51faa09d22c056fe221a45d2f7a3b8 | ||||||
|  | Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/Kconfig  | 16 ++++++++++++++++ | ||||||
|  |  drivers/mtd/Makefile |  1 + | ||||||
|  |  2 files changed, 17 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/Kconfig | ||||||
|  | +++ b/drivers/mtd/Kconfig | ||||||
|  | @@ -178,6 +178,22 @@ menu "Partition parsers" | ||||||
|  |  source "drivers/mtd/parsers/Kconfig" | ||||||
|  |  endmenu | ||||||
|  |   | ||||||
|  | +config MTD_MYLOADER_PARTS | ||||||
|  | +	tristate "MyLoader partition parsing" | ||||||
|  | +	depends on ADM5120 || ATH25 || ATH79 | ||||||
|  | +	---help--- | ||||||
|  | +	  MyLoader is a bootloader which allows the user to define partitions | ||||||
|  | +	  in flash devices, by putting a table in the second erase block | ||||||
|  | +	  on the device, similar to a partition table. This table gives the  | ||||||
|  | +	  offsets and lengths of the user defined partitions. | ||||||
|  | + | ||||||
|  | +	  If you need code which can detect and parse these tables, and | ||||||
|  | +	  register MTD 'partitions' corresponding to each image detected, | ||||||
|  | +	  enable this option. | ||||||
|  | + | ||||||
|  | +	  You will still need the parsing functions to be called by the driver | ||||||
|  | +	  for your particular device. It won't happen automatically. | ||||||
|  | + | ||||||
|  |  comment "User Modules And Translation Layers" | ||||||
|  |   | ||||||
|  |  # | ||||||
|  | --- a/drivers/mtd/Makefile | ||||||
|  | +++ b/drivers/mtd/Makefile | ||||||
|  | @@ -16,6 +16,7 @@ obj-$(CONFIG_MTD_AFS_PARTS)	+= afs.o | ||||||
|  |  obj-$(CONFIG_MTD_AR7_PARTS)	+= ar7part.o | ||||||
|  |  obj-$(CONFIG_MTD_BCM63XX_PARTS)	+= bcm63xxpart.o | ||||||
|  |  obj-$(CONFIG_MTD_BCM47XX_PARTS)	+= bcm47xxpart.o | ||||||
|  | +obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o | ||||||
|  |  obj-y				+= parsers/ | ||||||
|  |   | ||||||
|  |  # 'Users' - code which presents functionality to userspace. | ||||||
| @@ -0,0 +1,67 @@ | |||||||
|  | From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com> | ||||||
|  | Subject: [PATCH] mtd: bcm47xxpart: check for bad blocks when calculating offsets | ||||||
|  |  | ||||||
|  | Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/parsers/parser_trx.c | ||||||
|  | +++ b/drivers/mtd/parsers/parser_trx.c | ||||||
|  | @@ -29,6 +29,33 @@ struct trx_header { | ||||||
|  |  	uint32_t offset[3]; | ||||||
|  |  } __packed; | ||||||
|  |   | ||||||
|  | +/* | ||||||
|  | + * Calculate real end offset (address) for a given amount of data. It checks | ||||||
|  | + * all blocks skipping bad ones. | ||||||
|  | + */ | ||||||
|  | +static size_t parser_trx_real_offset(struct mtd_info *mtd, size_t bytes) | ||||||
|  | +{ | ||||||
|  | +	size_t real_offset = 0; | ||||||
|  | + | ||||||
|  | +	if (mtd_block_isbad(mtd, real_offset)) | ||||||
|  | +		pr_warn("Base offset shouldn't be at bad block"); | ||||||
|  | + | ||||||
|  | +	while (bytes >= mtd->erasesize) { | ||||||
|  | +		bytes -= mtd->erasesize; | ||||||
|  | +		real_offset += mtd->erasesize; | ||||||
|  | +		while (mtd_block_isbad(mtd, real_offset)) { | ||||||
|  | +			real_offset += mtd->erasesize; | ||||||
|  | + | ||||||
|  | +			if (real_offset >= mtd->size) | ||||||
|  | +				return real_offset - mtd->erasesize; | ||||||
|  | +		} | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	real_offset += bytes; | ||||||
|  | + | ||||||
|  | +	return real_offset; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static const char *parser_trx_data_part_name(struct mtd_info *master, | ||||||
|  |  					     size_t offset) | ||||||
|  |  { | ||||||
|  | @@ -83,21 +110,21 @@ static int parser_trx_parse(struct mtd_i | ||||||
|  |  	if (trx.offset[2]) { | ||||||
|  |  		part = &parts[curr_part++]; | ||||||
|  |  		part->name = "loader"; | ||||||
|  | -		part->offset = trx.offset[i]; | ||||||
|  | +		part->offset = parser_trx_real_offset(mtd, trx.offset[i]); | ||||||
|  |  		i++; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (trx.offset[i]) { | ||||||
|  |  		part = &parts[curr_part++]; | ||||||
|  |  		part->name = "linux"; | ||||||
|  | -		part->offset = trx.offset[i]; | ||||||
|  | +		part->offset = parser_trx_real_offset(mtd, trx.offset[i]); | ||||||
|  |  		i++; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (trx.offset[i]) { | ||||||
|  |  		part = &parts[curr_part++]; | ||||||
|  |  		part->name = parser_trx_data_part_name(mtd, trx.offset[i]); | ||||||
|  | -		part->offset = trx.offset[i]; | ||||||
|  | +		part->offset = parser_trx_real_offset(mtd, trx.offset[i]); | ||||||
|  |  		i++; | ||||||
|  |  	} | ||||||
|  |   | ||||||
| @@ -0,0 +1,37 @@ | |||||||
|  | From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com> | ||||||
|  | Subject: mtd: bcm47xxpart: detect T_Meter partition | ||||||
|  |  | ||||||
|  | It can be found on many Netgear devices. It consists of many 0x30 blocks | ||||||
|  | starting with 4D 54. | ||||||
|  |  | ||||||
|  | Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/bcm47xxpart.c | 10 ++++++++++ | ||||||
|  |  1 file changed, 10 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/bcm47xxpart.c | ||||||
|  | +++ b/drivers/mtd/bcm47xxpart.c | ||||||
|  | @@ -39,6 +39,7 @@ | ||||||
|  |  #define NVRAM_HEADER			0x48534C46	/* FLSH */ | ||||||
|  |  #define POT_MAGIC1			0x54544f50	/* POTT */ | ||||||
|  |  #define POT_MAGIC2			0x504f		/* OP */ | ||||||
|  | +#define T_METER_MAGIC			0x4D540000	/* MT */ | ||||||
|  |  #define ML_MAGIC1			0x39685a42 | ||||||
|  |  #define ML_MAGIC2			0x26594131 | ||||||
|  |  #define TRX_MAGIC			0x30524448 | ||||||
|  | @@ -182,6 +183,15 @@ static int bcm47xxpart_parse(struct mtd_ | ||||||
|  |  					     MTD_WRITEABLE); | ||||||
|  |  			continue; | ||||||
|  |  		} | ||||||
|  | + | ||||||
|  | +		/* T_Meter */ | ||||||
|  | +		if ((le32_to_cpu(buf[0x000 / 4]) & 0xFFFF0000) == T_METER_MAGIC && | ||||||
|  | +		    (le32_to_cpu(buf[0x030 / 4]) & 0xFFFF0000) == T_METER_MAGIC && | ||||||
|  | +		    (le32_to_cpu(buf[0x060 / 4]) & 0xFFFF0000) == T_METER_MAGIC) { | ||||||
|  | +			bcm47xxpart_add_part(&parts[curr_part++], "T_Meter", offset, | ||||||
|  | +					     MTD_WRITEABLE); | ||||||
|  | +			continue; | ||||||
|  | +		} | ||||||
|  |   | ||||||
|  |  		/* TRX */ | ||||||
|  |  		if (buf[0x000 / 4] == TRX_MAGIC) { | ||||||
							
								
								
									
										116
									
								
								target/linux/generic/pending-4.14/440-block2mtd_init.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								target/linux/generic/pending-4.14/440-block2mtd_init.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: block2mtd | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/devices/block2mtd.c | 30 ++++++++++++++++++++---------- | ||||||
|  |  1 file changed, 20 insertions(+), 10 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/devices/block2mtd.c | ||||||
|  | +++ b/drivers/mtd/devices/block2mtd.c | ||||||
|  | @@ -26,6 +26,7 @@ | ||||||
|  |  #include <linux/list.h> | ||||||
|  |  #include <linux/init.h> | ||||||
|  |  #include <linux/mtd/mtd.h> | ||||||
|  | +#include <linux/mtd/partitions.h> | ||||||
|  |  #include <linux/mutex.h> | ||||||
|  |  #include <linux/mount.h> | ||||||
|  |  #include <linux/slab.h> | ||||||
|  | @@ -219,7 +220,7 @@ static void block2mtd_free_device(struct | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  static struct block2mtd_dev *add_device(char *devname, int erase_size, | ||||||
|  | -		int timeout) | ||||||
|  | +		const char *mtdname, int timeout) | ||||||
|  |  { | ||||||
|  |  #ifndef MODULE | ||||||
|  |  	int i; | ||||||
|  | @@ -227,6 +228,7 @@ static struct block2mtd_dev *add_device( | ||||||
|  |  	const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL; | ||||||
|  |  	struct block_device *bdev = ERR_PTR(-ENODEV); | ||||||
|  |  	struct block2mtd_dev *dev; | ||||||
|  | +	struct mtd_partition *part; | ||||||
|  |  	char *name; | ||||||
|  |   | ||||||
|  |  	if (!devname) | ||||||
|  | @@ -283,13 +285,16 @@ static struct block2mtd_dev *add_device( | ||||||
|  |   | ||||||
|  |  	/* Setup the MTD structure */ | ||||||
|  |  	/* make the name contain the block device in */ | ||||||
|  | -	name = kasprintf(GFP_KERNEL, "block2mtd: %s", devname); | ||||||
|  | +	if (!mtdname) | ||||||
|  | +		mtdname = devname; | ||||||
|  | +	name = kmalloc(strlen(mtdname) + 1, GFP_KERNEL); | ||||||
|  |  	if (!name) | ||||||
|  |  		goto err_destroy_mutex; | ||||||
|  |   | ||||||
|  | +	strcpy(name, mtdname); | ||||||
|  |  	dev->mtd.name = name; | ||||||
|  |   | ||||||
|  | -	dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; | ||||||
|  | +	dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK & ~(erase_size - 1); | ||||||
|  |  	dev->mtd.erasesize = erase_size; | ||||||
|  |  	dev->mtd.writesize = 1; | ||||||
|  |  	dev->mtd.writebufsize = PAGE_SIZE; | ||||||
|  | @@ -302,7 +307,11 @@ static struct block2mtd_dev *add_device( | ||||||
|  |  	dev->mtd.priv = dev; | ||||||
|  |  	dev->mtd.owner = THIS_MODULE; | ||||||
|  |   | ||||||
|  | -	if (mtd_device_register(&dev->mtd, NULL, 0)) { | ||||||
|  | +	part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL); | ||||||
|  | +	part->name = name; | ||||||
|  | +	part->offset = 0; | ||||||
|  | +	part->size = dev->mtd.size; | ||||||
|  | +	if (mtd_device_register(&dev->mtd, part, 1)) { | ||||||
|  |  		/* Device didn't get added, so free the entry */ | ||||||
|  |  		goto err_destroy_mutex; | ||||||
|  |  	} | ||||||
|  | @@ -310,8 +319,7 @@ static struct block2mtd_dev *add_device( | ||||||
|  |  	list_add(&dev->list, &blkmtd_device_list); | ||||||
|  |  	pr_info("mtd%d: [%s] erase_size = %dKiB [%d]\n", | ||||||
|  |  		dev->mtd.index, | ||||||
|  | -		dev->mtd.name + strlen("block2mtd: "), | ||||||
|  | -		dev->mtd.erasesize >> 10, dev->mtd.erasesize); | ||||||
|  | +		mtdname, dev->mtd.erasesize >> 10, dev->mtd.erasesize); | ||||||
|  |  	return dev; | ||||||
|  |   | ||||||
|  |  err_destroy_mutex: | ||||||
|  | @@ -384,7 +392,7 @@ static int block2mtd_setup2(const char * | ||||||
|  |  	/* 80 for device, 12 for erase size, 80 for name, 8 for timeout */ | ||||||
|  |  	char buf[80 + 12 + 80 + 8]; | ||||||
|  |  	char *str = buf; | ||||||
|  | -	char *token[2]; | ||||||
|  | +	char *token[3]; | ||||||
|  |  	char *name; | ||||||
|  |  	size_t erase_size = PAGE_SIZE; | ||||||
|  |  	unsigned long timeout = MTD_DEFAULT_TIMEOUT; | ||||||
|  | @@ -398,7 +406,7 @@ static int block2mtd_setup2(const char * | ||||||
|  |  	strcpy(str, val); | ||||||
|  |  	kill_final_newline(str); | ||||||
|  |   | ||||||
|  | -	for (i = 0; i < 2; i++) | ||||||
|  | +	for (i = 0; i < 3; i++) | ||||||
|  |  		token[i] = strsep(&str, ","); | ||||||
|  |   | ||||||
|  |  	if (str) { | ||||||
|  | @@ -424,8 +432,10 @@ static int block2mtd_setup2(const char * | ||||||
|  |  			return 0; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  | +	if (token[2] && (strlen(token[2]) + 1 > 80)) | ||||||
|  | +		pr_err("mtd device name too long\n"); | ||||||
|  |   | ||||||
|  | -	add_device(name, erase_size, timeout); | ||||||
|  | +	add_device(name, erase_size, token[2], timeout); | ||||||
|  |   | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  | @@ -459,7 +469,7 @@ static int block2mtd_setup(const char *v | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200); | ||||||
|  | -MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\""); | ||||||
|  | +MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>[,<name>]]\""); | ||||||
|  |   | ||||||
|  |  static int __init block2mtd_init(void) | ||||||
|  |  { | ||||||
							
								
								
									
										47
									
								
								target/linux/generic/pending-4.14/441-block2mtd_probe.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								target/linux/generic/pending-4.14/441-block2mtd_probe.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: block2mtd | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/devices/block2mtd.c | 9 ++++++--- | ||||||
|  |  1 file changed, 6 insertions(+), 3 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/devices/block2mtd.c | ||||||
|  | +++ b/drivers/mtd/devices/block2mtd.c | ||||||
|  | @@ -392,7 +392,7 @@ static int block2mtd_setup2(const char * | ||||||
|  |  	/* 80 for device, 12 for erase size, 80 for name, 8 for timeout */ | ||||||
|  |  	char buf[80 + 12 + 80 + 8]; | ||||||
|  |  	char *str = buf; | ||||||
|  | -	char *token[3]; | ||||||
|  | +	char *token[4]; | ||||||
|  |  	char *name; | ||||||
|  |  	size_t erase_size = PAGE_SIZE; | ||||||
|  |  	unsigned long timeout = MTD_DEFAULT_TIMEOUT; | ||||||
|  | @@ -406,7 +406,7 @@ static int block2mtd_setup2(const char * | ||||||
|  |  	strcpy(str, val); | ||||||
|  |  	kill_final_newline(str); | ||||||
|  |   | ||||||
|  | -	for (i = 0; i < 3; i++) | ||||||
|  | +	for (i = 0; i < 4; i++) | ||||||
|  |  		token[i] = strsep(&str, ","); | ||||||
|  |   | ||||||
|  |  	if (str) { | ||||||
|  | @@ -435,6 +435,9 @@ static int block2mtd_setup2(const char * | ||||||
|  |  	if (token[2] && (strlen(token[2]) + 1 > 80)) | ||||||
|  |  		pr_err("mtd device name too long\n"); | ||||||
|  |   | ||||||
|  | +	if (token[3] && kstrtoul(token[3], 0, &timeout)) | ||||||
|  | +		pr_err("invalid timeout\n"); | ||||||
|  | + | ||||||
|  |  	add_device(name, erase_size, token[2], timeout); | ||||||
|  |   | ||||||
|  |  	return 0; | ||||||
|  | @@ -469,7 +472,7 @@ static int block2mtd_setup(const char *v | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200); | ||||||
|  | -MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>[,<name>]]\""); | ||||||
|  | +MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>[,<name>[,<timeout>]]]\""); | ||||||
|  |   | ||||||
|  |  static int __init block2mtd_init(void) | ||||||
|  |  { | ||||||
| @@ -0,0 +1,25 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: kernel: disable cfi cmdset 0002 erase suspend | ||||||
|  |  | ||||||
|  | on some platforms, erase suspend leads to data corruption and lockups when write | ||||||
|  | ops collide with erase ops. this has been observed on the buffalo wzr-hp-g300nh. | ||||||
|  | rather than play whack-a-mole with a hard to reproduce issue on a variety of devices, | ||||||
|  | simply disable erase suspend, as it will usually not produce any useful gain on | ||||||
|  | the small filesystems used on embedded hardware. | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/chips/cfi_cmdset_0002.c | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/chips/cfi_cmdset_0002.c | ||||||
|  | +++ b/drivers/mtd/chips/cfi_cmdset_0002.c | ||||||
|  | @@ -811,7 +811,7 @@ static int get_chip(struct map_info *map | ||||||
|  |  		return 0; | ||||||
|  |   | ||||||
|  |  	case FL_ERASING: | ||||||
|  | -		if (!cfip || !(cfip->EraseSuspend & (0x1|0x2)) || | ||||||
|  | +		if (1 /* no suspend */ || !cfip || !(cfip->EraseSuspend & (0x1|0x2)) || | ||||||
|  |  		    !(mode == FL_READY || mode == FL_POINT || | ||||||
|  |  		    (mode == FL_WRITING && (cfip->EraseSuspend & 0x2)))) | ||||||
|  |  			goto sleep; | ||||||
| @@ -0,0 +1,17 @@ | |||||||
|  | From: George Kashperko <george@znau.edu.ua> | ||||||
|  | Subject: Issue map read after Write Buffer Load command to ensure chip is ready to receive data. | ||||||
|  |  | ||||||
|  | Signed-off-by: George Kashperko <george@znau.edu.ua> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/chips/cfi_cmdset_0002.c |    1 + | ||||||
|  |  1 file changed, 1 insertion(+) | ||||||
|  | --- a/drivers/mtd/chips/cfi_cmdset_0002.c | ||||||
|  | +++ b/drivers/mtd/chips/cfi_cmdset_0002.c | ||||||
|  | @@ -1832,6 +1832,7 @@ static int __xipram do_write_buffer(stru | ||||||
|  |   | ||||||
|  |  	/* Write Buffer Load */ | ||||||
|  |  	map_write(map, CMD(0x25), cmd_adr); | ||||||
|  | +	(void) map_read(map, cmd_adr); | ||||||
|  |   | ||||||
|  |  	chip->state = FL_WRITING_TO_BUFFER; | ||||||
|  |   | ||||||
| @@ -0,0 +1,18 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: Disable software protection bits for Macronix flashes. | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/spi-nor/spi-nor.c | 1 + | ||||||
|  |  1 file changed, 1 insertion(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/spi-nor/spi-nor.c | ||||||
|  | +++ b/drivers/mtd/spi-nor/spi-nor.c | ||||||
|  | @@ -2715,6 +2715,7 @@ int spi_nor_scan(struct spi_nor *nor, co | ||||||
|  |   | ||||||
|  |  	if (JEDEC_MFR(info) == SNOR_MFR_ATMEL || | ||||||
|  |  	    JEDEC_MFR(info) == SNOR_MFR_INTEL || | ||||||
|  | +	    JEDEC_MFR(info) == SNOR_MFR_MACRONIX || | ||||||
|  |  	    JEDEC_MFR(info) == SNOR_MFR_SST || | ||||||
|  |  	    info->flags & SPI_NOR_HAS_LOCK) { | ||||||
|  |  		write_enable(nor); | ||||||
| @@ -0,0 +1,56 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Sat, 4 Nov 2017 07:40:23 +0100 | ||||||
|  | Subject: [PATCH] mtd: spi-nor: support limiting 4K sectors support based on | ||||||
|  |  flash size | ||||||
|  |  | ||||||
|  | Some devices need 4K sectors to be able to deal with small flash chips. | ||||||
|  | For instance, w25x05 is 64 KiB in size, and without 4K sectors, the | ||||||
|  | entire chip is just one erase block. | ||||||
|  | On bigger flash chip sizes, using 4K sectors can significantly slow down | ||||||
|  | many operations, including using a writable filesystem. There are several | ||||||
|  | platforms where it makes sense to use a single kernel on both kinds of | ||||||
|  | devices. | ||||||
|  |  | ||||||
|  | To support this properly, allow configuring an upper flash chip size | ||||||
|  | limit for 4K sectors support. | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/spi-nor/Kconfig | ||||||
|  | +++ b/drivers/mtd/spi-nor/Kconfig | ||||||
|  | @@ -39,6 +39,17 @@ config SPI_ASPEED_SMC | ||||||
|  |  	  and support for the SPI flash memory controller (SPI) for | ||||||
|  |  	  the host firmware. The implementation only supports SPI NOR. | ||||||
|  |   | ||||||
|  | +config MTD_SPI_NOR_USE_4K_SECTORS_LIMIT | ||||||
|  | +	int "Maximum flash chip size to use 4K sectors on (in KiB)" | ||||||
|  | +	depends on MTD_SPI_NOR_USE_4K_SECTORS | ||||||
|  | +	default "4096" | ||||||
|  | +	help | ||||||
|  | +	  There are many flash chips that support 4K sectors, but are so large | ||||||
|  | +	  that using them significantly slows down writing large amounts of | ||||||
|  | +	  data or using a writable filesystem. | ||||||
|  | +	  Any flash chip larger than the size specified in this option will | ||||||
|  | +	  not use 4K sectors. | ||||||
|  | + | ||||||
|  |  config SPI_ATMEL_QUADSPI | ||||||
|  |  	tristate "Atmel Quad SPI Controller" | ||||||
|  |  	depends on ARCH_AT91 || (ARM && COMPILE_TEST) | ||||||
|  | --- a/drivers/mtd/spi-nor/spi-nor.c | ||||||
|  | +++ b/drivers/mtd/spi-nor/spi-nor.c | ||||||
|  | @@ -2562,10 +2562,12 @@ static int spi_nor_select_erase(struct s | ||||||
|  |   | ||||||
|  |  #ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS | ||||||
|  |  	/* prefer "small sector" erase if possible */ | ||||||
|  | -	if (info->flags & SECT_4K) { | ||||||
|  | +	if ((info->flags & SECT_4K) && (mtd->size <= | ||||||
|  | +	    CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT * 1024)) { | ||||||
|  |  		nor->erase_opcode = SPINOR_OP_BE_4K; | ||||||
|  |  		mtd->erasesize = 4096; | ||||||
|  | -	} else if (info->flags & SECT_4K_PMC) { | ||||||
|  | +	} else if ((info->flags & SECT_4K_PMC) && (mtd->size <= | ||||||
|  | +		   CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT * 1024)) { | ||||||
|  |  		nor->erase_opcode = SPINOR_OP_BE_4K_PMC; | ||||||
|  |  		mtd->erasesize = 4096; | ||||||
|  |  	} else | ||||||
| @@ -0,0 +1,18 @@ | |||||||
|  | From: Piotr Dymacz <pepe2k@gmail.com> | ||||||
|  | Subject: kernel/mtd: add support for EON EN25Q128 | ||||||
|  |  | ||||||
|  | Signed-off-by: Piotr Dymacz <pepe2k@gmail.com> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/spi-nor/spi-nor.c | 1 + | ||||||
|  |  1 file changed, 1 insertion(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/spi-nor/spi-nor.c | ||||||
|  | +++ b/drivers/mtd/spi-nor/spi-nor.c | ||||||
|  | @@ -954,6 +954,7 @@ static const struct flash_info spi_nor_i | ||||||
|  |  	{ "en25q32b",   INFO(0x1c3016, 0, 64 * 1024,   64, 0) }, | ||||||
|  |  	{ "en25p64",    INFO(0x1c2017, 0, 64 * 1024,  128, 0) }, | ||||||
|  |  	{ "en25q64",    INFO(0x1c3017, 0, 64 * 1024,  128, SECT_4K) }, | ||||||
|  | +	{ "en25q128",   INFO(0x1c3018, 0, 64 * 1024,  256, SECT_4K) }, | ||||||
|  |  	{ "en25qh128",  INFO(0x1c7018, 0, 64 * 1024,  256, 0) }, | ||||||
|  |  	{ "en25qh256",  INFO(0x1c7019, 0, 64 * 1024,  512, 0) }, | ||||||
|  |  	{ "en25s64",	INFO(0x1c3817, 0, 64 * 1024,  128, SECT_4K) }, | ||||||
| @@ -0,0 +1,18 @@ | |||||||
|  | From: André Valentin <avalentin@marcant.net> | ||||||
|  | Subject: linux/mtd: add id for mx25u3235f needed by ZyXEL NBG6817 | ||||||
|  |  | ||||||
|  | Signed-off-by: André Valentin <avalentin@marcant.net> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/spi-nor/spi-nor.c | 1 + | ||||||
|  |  1 file changed, 1 insertion(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/spi-nor/spi-nor.c | ||||||
|  | +++ b/drivers/mtd/spi-nor/spi-nor.c | ||||||
|  | @@ -1016,6 +1016,7 @@ static const struct flash_info spi_nor_i | ||||||
|  |  	{ "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, SECT_4K) }, | ||||||
|  |  	{ "mx25l3255e",  INFO(0xc29e16, 0, 64 * 1024,  64, SECT_4K) }, | ||||||
|  |  	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) }, | ||||||
|  | +	{ "mx25u3235f",	 INFO(0xc22536, 0, 64 * 1024, 64, 0) }, | ||||||
|  |  	{ "mx25u2033e",  INFO(0xc22532, 0, 64 * 1024,   4, SECT_4K) }, | ||||||
|  |  	{ "mx25u4035",   INFO(0xc22533, 0, 64 * 1024,   8, SECT_4K) }, | ||||||
|  |  	{ "mx25u8035",   INFO(0xc22534, 0, 64 * 1024,  16, SECT_4K) }, | ||||||
| @@ -0,0 +1,38 @@ | |||||||
|  | From: Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | Subject: kernel/3.1[02]: move MTD root device setup code to mtdcore | ||||||
|  |  | ||||||
|  | The current code only allows to automatically set | ||||||
|  | root device on MTD partitions. Move the code to MTD | ||||||
|  | core to allow to use it with all MTD devices. | ||||||
|  |  | ||||||
|  | Signed-off-by: Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/mtdcore.c | 10 ++++++++++ | ||||||
|  |  1 file changed, 10 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/mtdcore.c | ||||||
|  | +++ b/drivers/mtd/mtdcore.c | ||||||
|  | @@ -41,6 +41,7 @@ | ||||||
|  |  #include <linux/reboot.h> | ||||||
|  |  #include <linux/leds.h> | ||||||
|  |  #include <linux/debugfs.h> | ||||||
|  | +#include <linux/root_dev.h> | ||||||
|  |   | ||||||
|  |  #include <linux/mtd/mtd.h> | ||||||
|  |  #include <linux/mtd/partitions.h> | ||||||
|  | @@ -578,6 +579,15 @@ int add_mtd_device(struct mtd_info *mtd) | ||||||
|  |  	   of this try_ nonsense, and no bitching about it | ||||||
|  |  	   either. :) */ | ||||||
|  |  	__module_get(THIS_MODULE); | ||||||
|  | + | ||||||
|  | +	if (!strcmp(mtd->name, "rootfs") && | ||||||
|  | +	    IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && | ||||||
|  | +	    ROOT_DEV == 0) { | ||||||
|  | +		pr_notice("mtd: device %d (%s) set to be root filesystem\n", | ||||||
|  | +			  mtd->index, mtd->name); | ||||||
|  | +		ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	return 0; | ||||||
|  |   | ||||||
|  |  fail_added: | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	 Hauke Mehrtens
					Hauke Mehrtens