kernel: add linux 5.10 support
Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
		| @@ -7,8 +7,10 @@ ifdef CONFIG_TESTING_KERNEL | |||||||
| endif | endif | ||||||
|  |  | ||||||
| LINUX_VERSION-5.4 = .98 | LINUX_VERSION-5.4 = .98 | ||||||
|  | LINUX_VERSION-5.10 = .14 | ||||||
|  |  | ||||||
| LINUX_KERNEL_HASH-5.4.98 = 83a248d6fbe388f133769d736f36b754767abc9d66f1c034b537ad778fbd46b1 | LINUX_KERNEL_HASH-5.4.98 = 83a248d6fbe388f133769d736f36b754767abc9d66f1c034b537ad778fbd46b1 | ||||||
|  | LINUX_KERNEL_HASH-5.10.14 = fa27b79f198b5be969e497ed5461860df48e0591c85e60699fc8be26837a1d2a | ||||||
|  |  | ||||||
| remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1)))) | remove_uri_prefix=$(subst git://,,$(subst http://,,$(subst https://,,$(1)))) | ||||||
| sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1))))))) | sanitize_uri=$(call qstrip,$(subst @,_,$(subst :,_,$(subst .,_,$(subst -,_,$(subst /,_,$(1))))))) | ||||||
|   | |||||||
| @@ -537,16 +537,24 @@ endef | |||||||
| $(eval $(call KernelPackage,scsi-generic)) | $(eval $(call KernelPackage,scsi-generic)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | define KernelPackage/cdrom | ||||||
|  |   TITLE:=Kernel library module for CD / DVD drives | ||||||
|  |   KCONFIG:=CONFIG_CDROM | ||||||
|  |   HIDDEN:=1 | ||||||
|  |   FILES:=$(LINUX_DIR)/drivers/cdrom/cdrom.ko | ||||||
|  | endef | ||||||
|  |  | ||||||
|  | $(eval $(call KernelPackage,cdrom)) | ||||||
|  |  | ||||||
|  |  | ||||||
| define KernelPackage/scsi-cdrom | define KernelPackage/scsi-cdrom | ||||||
|   SUBMENU:=$(BLOCK_MENU) |   SUBMENU:=$(BLOCK_MENU) | ||||||
|   TITLE:=Kernel support for CD / DVD drives |   TITLE:=Kernel support for CD / DVD drives | ||||||
|   DEPENDS:=+kmod-scsi-core |   DEPENDS:=+kmod-scsi-core +kmod-cdrom | ||||||
|   KCONFIG:= \ |   KCONFIG:= \ | ||||||
|     CONFIG_BLK_DEV_SR \ |     CONFIG_BLK_DEV_SR \ | ||||||
|     CONFIG_BLK_DEV_SR_VENDOR=n |     CONFIG_BLK_DEV_SR_VENDOR=n | ||||||
|   FILES:= \ |   FILES:=$(LINUX_DIR)/drivers/scsi/sr_mod.ko | ||||||
|     $(LINUX_DIR)/drivers/cdrom/cdrom.ko \ |  | ||||||
|     $(LINUX_DIR)/drivers/scsi/sr_mod.ko |  | ||||||
|   AUTOLOAD:=$(call AutoLoad,45,sr_mod) |   AUTOLOAD:=$(call AutoLoad,45,sr_mod) | ||||||
| endef | endef | ||||||
|  |  | ||||||
|   | |||||||
| @@ -243,6 +243,7 @@ $(eval $(call KernelPackage,fs-fscache)) | |||||||
| define KernelPackage/fs-hfs | define KernelPackage/fs-hfs | ||||||
|   SUBMENU:=$(FS_MENU) |   SUBMENU:=$(FS_MENU) | ||||||
|   TITLE:=HFS filesystem support |   TITLE:=HFS filesystem support | ||||||
|  |   DEPENDS:=+kmod-cdrom | ||||||
|   KCONFIG:=CONFIG_HFS_FS |   KCONFIG:=CONFIG_HFS_FS | ||||||
|   FILES:=$(LINUX_DIR)/fs/hfs/hfs.ko |   FILES:=$(LINUX_DIR)/fs/hfs/hfs.ko | ||||||
|   AUTOLOAD:=$(call AutoLoad,30,hfs) |   AUTOLOAD:=$(call AutoLoad,30,hfs) | ||||||
| @@ -259,6 +260,7 @@ $(eval $(call KernelPackage,fs-hfs)) | |||||||
| define KernelPackage/fs-hfsplus | define KernelPackage/fs-hfsplus | ||||||
|   SUBMENU:=$(FS_MENU) |   SUBMENU:=$(FS_MENU) | ||||||
|   TITLE:=HFS+ filesystem support |   TITLE:=HFS+ filesystem support | ||||||
|  |   DEPENDS:=+kmod-cdrom | ||||||
|   KCONFIG:=CONFIG_HFSPLUS_FS |   KCONFIG:=CONFIG_HFSPLUS_FS | ||||||
|   FILES:=$(LINUX_DIR)/fs/hfsplus/hfsplus.ko |   FILES:=$(LINUX_DIR)/fs/hfsplus/hfsplus.ko | ||||||
|   AUTOLOAD:=$(call AutoLoad,30,hfsplus) |   AUTOLOAD:=$(call AutoLoad,30,hfsplus) | ||||||
| @@ -275,7 +277,7 @@ $(eval $(call KernelPackage,fs-hfsplus)) | |||||||
| define KernelPackage/fs-isofs | define KernelPackage/fs-isofs | ||||||
|   SUBMENU:=$(FS_MENU) |   SUBMENU:=$(FS_MENU) | ||||||
|   TITLE:=ISO9660 filesystem support |   TITLE:=ISO9660 filesystem support | ||||||
|   DEPENDS:=+kmod-lib-zlib-inflate |   DEPENDS:=+kmod-lib-zlib-inflate +kmod-cdrom | ||||||
|   KCONFIG:=CONFIG_ISO9660_FS CONFIG_JOLIET=y CONFIG_ZISOFS=n |   KCONFIG:=CONFIG_ISO9660_FS CONFIG_JOLIET=y CONFIG_ZISOFS=n | ||||||
|   FILES:=$(LINUX_DIR)/fs/isofs/isofs.ko |   FILES:=$(LINUX_DIR)/fs/isofs/isofs.ko | ||||||
|   AUTOLOAD:=$(call AutoLoad,30,isofs) |   AUTOLOAD:=$(call AutoLoad,30,isofs) | ||||||
| @@ -513,7 +515,7 @@ define KernelPackage/fs-udf | |||||||
|   KCONFIG:=CONFIG_UDF_FS |   KCONFIG:=CONFIG_UDF_FS | ||||||
|   FILES:=$(LINUX_DIR)/fs/udf/udf.ko |   FILES:=$(LINUX_DIR)/fs/udf/udf.ko | ||||||
|   AUTOLOAD:=$(call AutoLoad,30,udf) |   AUTOLOAD:=$(call AutoLoad,30,udf) | ||||||
|   DEPENDS:=+kmod-lib-crc-itu-t |   DEPENDS:=+kmod-lib-crc-itu-t +kmod-cdrom | ||||||
|   $(call AddDepends/nls) |   $(call AddDepends/nls) | ||||||
| endef | endef | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1178,7 +1178,7 @@ $(eval $(call KernelPackage,sfp)) | |||||||
| define KernelPackage/igc | define KernelPackage/igc | ||||||
|   SUBMENU:=$(NETWORK_DEVICES_MENU) |   SUBMENU:=$(NETWORK_DEVICES_MENU) | ||||||
|   TITLE:=Intel(R) Ethernet Controller I225 Series support |   TITLE:=Intel(R) Ethernet Controller I225 Series support | ||||||
|   DEPENDS:=@PCI_SUPPORT |   DEPENDS:=@PCI_SUPPORT +kmod-ptp | ||||||
|   KCONFIG:=CONFIG_IGC |   KCONFIG:=CONFIG_IGC | ||||||
|   FILES:=$(LINUX_DIR)/drivers/net/ethernet/intel/igc/igc.ko |   FILES:=$(LINUX_DIR)/drivers/net/ethernet/intel/igc/igc.ko | ||||||
|   AUTOLOAD:=$(call AutoProbe,igc) |   AUTOLOAD:=$(call AutoProbe,igc) | ||||||
|   | |||||||
| @@ -155,7 +155,7 @@ define KernelPackage/nf-flow | |||||||
|   DEPENDS:=+kmod-nf-conntrack |   DEPENDS:=+kmod-nf-conntrack | ||||||
|   FILES:= \ |   FILES:= \ | ||||||
| 	$(LINUX_DIR)/net/netfilter/nf_flow_table.ko \ | 	$(LINUX_DIR)/net/netfilter/nf_flow_table.ko \ | ||||||
| 	$(LINUX_DIR)/net/netfilter/nf_flow_table_hw.ko | 	$(if $(CONFIG_LINUX_5_4),$(LINUX_DIR)/net/netfilter/nf_flow_table_hw.ko) | ||||||
|   AUTOLOAD:=$(call AutoProbe,nf_flow_table nf_flow_table_hw) |   AUTOLOAD:=$(call AutoProbe,nf_flow_table nf_flow_table_hw) | ||||||
| endef | endef | ||||||
|  |  | ||||||
| @@ -1052,7 +1052,7 @@ $(eval $(call KernelPackage,ipt-rpfilter)) | |||||||
| define KernelPackage/nft-core | define KernelPackage/nft-core | ||||||
|   SUBMENU:=$(NF_MENU) |   SUBMENU:=$(NF_MENU) | ||||||
|   TITLE:=Netfilter nf_tables support |   TITLE:=Netfilter nf_tables support | ||||||
|   DEPENDS:=+kmod-nfnetlink +kmod-nf-reject +IPV6:kmod-nf-reject6 +IPV6:kmod-nf-conntrack6 +kmod-nf-nat |   DEPENDS:=+kmod-nfnetlink +kmod-nf-reject +IPV6:kmod-nf-reject6 +IPV6:kmod-nf-conntrack6 +kmod-nf-nat +kmod-lib-crc32c | ||||||
|   FILES:=$(foreach mod,$(NFT_CORE-m),$(LINUX_DIR)/net/$(mod).ko) |   FILES:=$(foreach mod,$(NFT_CORE-m),$(LINUX_DIR)/net/$(mod).ko) | ||||||
|   AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_CORE-m))) |   AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_CORE-m))) | ||||||
|   KCONFIG:= \ |   KCONFIG:= \ | ||||||
|   | |||||||
| @@ -1387,7 +1387,7 @@ define KernelPackage/usb-net-cdc-ncm | |||||||
|   KCONFIG:=CONFIG_USB_NET_CDC_NCM |   KCONFIG:=CONFIG_USB_NET_CDC_NCM | ||||||
|   FILES:= $(LINUX_DIR)/drivers/$(USBNET_DIR)/cdc_ncm.ko |   FILES:= $(LINUX_DIR)/drivers/$(USBNET_DIR)/cdc_ncm.ko | ||||||
|   AUTOLOAD:=$(call AutoProbe,cdc_ncm) |   AUTOLOAD:=$(call AutoProbe,cdc_ncm) | ||||||
|   $(call AddDepends/usb-net) |   $(call AddDepends/usb-net,+kmod-usb-net-cdc-ether) | ||||||
| endef | endef | ||||||
|  |  | ||||||
| define KernelPackage/usb-net-cdc-ncm/description | define KernelPackage/usb-net-cdc-ncm/description | ||||||
|   | |||||||
| @@ -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,21 @@ | |||||||
|  | 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 | ||||||
|  | @@ -506,7 +506,7 @@ KBUILD_LDFLAGS_MODULE := | ||||||
|  |  KBUILD_LDFLAGS := | ||||||
|  |  CLANG_FLAGS := | ||||||
|  |   | ||||||
|  | -export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC | ||||||
|  | +export ARCH SRCARCH SUBARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC | ||||||
|  |  export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL | ||||||
|  |  export PERL PYTHON PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX | ||||||
|  |  export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD | ||||||
| @@ -0,0 +1,106 @@ | |||||||
|  | From: Pablo Neira Ayuso <pablo@netfilter.org> | ||||||
|  | Date: Thu, 25 Jan 2018 12:58:55 +0100 | ||||||
|  | Subject: [PATCH] netfilter: nft_flow_offload: handle netdevice events from | ||||||
|  |  nf_flow_table | ||||||
|  |  | ||||||
|  | Move the code that deals with device events to the core. | ||||||
|  |  | ||||||
|  | Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/net/netfilter/nf_flow_table_core.c | ||||||
|  | +++ b/net/netfilter/nf_flow_table_core.c | ||||||
|  | @@ -577,13 +577,41 @@ void nf_flow_table_free(struct nf_flowta | ||||||
|  |  } | ||||||
|  |  EXPORT_SYMBOL_GPL(nf_flow_table_free); | ||||||
|  |   | ||||||
|  | +static int nf_flow_table_netdev_event(struct notifier_block *this, | ||||||
|  | +				      unsigned long event, void *ptr) | ||||||
|  | +{ | ||||||
|  | +	struct net_device *dev = netdev_notifier_info_to_dev(ptr); | ||||||
|  | + | ||||||
|  | +	if (event != NETDEV_DOWN) | ||||||
|  | +		return NOTIFY_DONE; | ||||||
|  | + | ||||||
|  | +	nf_flow_table_cleanup(dev); | ||||||
|  | + | ||||||
|  | +	return NOTIFY_DONE; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static struct notifier_block flow_offload_netdev_notifier = { | ||||||
|  | +	.notifier_call	= nf_flow_table_netdev_event, | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  |  static int __init nf_flow_table_module_init(void) | ||||||
|  |  { | ||||||
|  | -	return nf_flow_table_offload_init(); | ||||||
|  | +	int ret; | ||||||
|  | + | ||||||
|  | +	ret = nf_flow_table_offload_init(); | ||||||
|  | +	if (ret) | ||||||
|  | +		return ret; | ||||||
|  | + | ||||||
|  | +	ret = register_netdevice_notifier(&flow_offload_netdev_notifier); | ||||||
|  | +	if (ret) | ||||||
|  | +		nf_flow_table_offload_exit(); | ||||||
|  | + | ||||||
|  | +	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void __exit nf_flow_table_module_exit(void) | ||||||
|  |  { | ||||||
|  | +	unregister_netdevice_notifier(&flow_offload_netdev_notifier); | ||||||
|  |  	nf_flow_table_offload_exit(); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | --- a/net/netfilter/nft_flow_offload.c | ||||||
|  | +++ b/net/netfilter/nft_flow_offload.c | ||||||
|  | @@ -237,47 +237,14 @@ static struct nft_expr_type nft_flow_off | ||||||
|  |  	.owner		= THIS_MODULE, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | -static int flow_offload_netdev_event(struct notifier_block *this, | ||||||
|  | -				     unsigned long event, void *ptr) | ||||||
|  | -{ | ||||||
|  | -	struct net_device *dev = netdev_notifier_info_to_dev(ptr); | ||||||
|  | - | ||||||
|  | -	if (event != NETDEV_DOWN) | ||||||
|  | -		return NOTIFY_DONE; | ||||||
|  | - | ||||||
|  | -	nf_flow_table_cleanup(dev); | ||||||
|  | - | ||||||
|  | -	return NOTIFY_DONE; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static struct notifier_block flow_offload_netdev_notifier = { | ||||||
|  | -	.notifier_call	= flow_offload_netdev_event, | ||||||
|  | -}; | ||||||
|  | - | ||||||
|  |  static int __init nft_flow_offload_module_init(void) | ||||||
|  |  { | ||||||
|  | -	int err; | ||||||
|  | - | ||||||
|  | -	err = register_netdevice_notifier(&flow_offload_netdev_notifier); | ||||||
|  | -	if (err) | ||||||
|  | -		goto err; | ||||||
|  | - | ||||||
|  | -	err = nft_register_expr(&nft_flow_offload_type); | ||||||
|  | -	if (err < 0) | ||||||
|  | -		goto register_expr; | ||||||
|  | - | ||||||
|  | -	return 0; | ||||||
|  | - | ||||||
|  | -register_expr: | ||||||
|  | -	unregister_netdevice_notifier(&flow_offload_netdev_notifier); | ||||||
|  | -err: | ||||||
|  | -	return err; | ||||||
|  | +	return nft_register_expr(&nft_flow_offload_type); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void __exit nft_flow_offload_module_exit(void) | ||||||
|  |  { | ||||||
|  |  	nft_unregister_expr(&nft_flow_offload_type); | ||||||
|  | -	unregister_netdevice_notifier(&flow_offload_netdev_notifier); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  module_init(nft_flow_offload_module_init); | ||||||
							
								
								
									
										6941
									
								
								target/linux/generic/config-5.10
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6941
									
								
								target/linux/generic/config-5.10
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,7 +1,11 @@ | |||||||
| # CONFIG_ARCH_(ENABLE|HAS|HAVE|INLINE|SUPPORTS|USE|WANT)_.* is not set | # CONFIG_ARM64_AS_.* is not set | ||||||
|  | # CONFIG_ARM64_CONT_.*_SHIFT is not set | ||||||
|  | # CONFIG_ARCH_(ENABLE|HAS|HAVE|INLINE|SUPPORTS|USE|WANT|STACKWALK)_.* is not set | ||||||
| # CONFIG_AS_.* is not set | # CONFIG_AS_.* is not set | ||||||
| # CONFIG_CC_(CAN|HAS|IS|VERSION)_.* is not set | # CONFIG_CC_(CAN|HAS|IS|VERSION)_.* is not set | ||||||
| # CONFIG_LD_.* is not set | # CONFIG_LD_.* is not set | ||||||
| # CONFIG_GCC_VERSION is not set | # CONFIG_GCC_VERSION is not set | ||||||
| # CONFIG_INLINE_.* is not set | # CONFIG_INLINE_.* is not set | ||||||
| # CONFIG_HAVE_(?!(ARCH_TIMER|TCM|SMP)).* is not set | # CONFIG_HAVE_(?!(ARCH_TIMER|TCM|SMP)).* is not set | ||||||
|  | # CONFIG_SET_FS is not set | ||||||
|  | # CONFIG_TASKS_.* is not set | ||||||
|   | |||||||
| @@ -513,6 +513,8 @@ ar8216_read_port_link(struct ar8xxx_priv *priv, int port, | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #ifdef CONFIG_ETHERNET_PACKET_MANGLE | ||||||
|  |  | ||||||
| static struct sk_buff * | static struct sk_buff * | ||||||
| ar8216_mangle_tx(struct net_device *dev, struct sk_buff *skb) | ar8216_mangle_tx(struct net_device *dev, struct sk_buff *skb) | ||||||
| { | { | ||||||
| @@ -579,6 +581,8 @@ ar8216_mangle_rx(struct net_device *dev, struct sk_buff *skb) | |||||||
| 	buf[15 + 2] = vlan & 0xff; | 	buf[15 + 2] = vlan & 0xff; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #endif | ||||||
|  |  | ||||||
| int | int | ||||||
| ar8216_wait_bit(struct ar8xxx_priv *priv, int reg, u32 mask, u32 val) | ar8216_wait_bit(struct ar8xxx_priv *priv, int reg, u32 mask, u32 val) | ||||||
| { | { | ||||||
| @@ -2449,6 +2453,7 @@ ar8xxx_phy_config_init(struct phy_device *phydev) | |||||||
| 	if (ret) | 	if (ret) | ||||||
| 		return ret; | 		return ret; | ||||||
|  |  | ||||||
|  | #ifdef CONFIG_ETHERNET_PACKET_MANGLE | ||||||
| 	/* VID fixup only needed on ar8216 */ | 	/* VID fixup only needed on ar8216 */ | ||||||
| 	if (chip_is_ar8216(priv)) { | 	if (chip_is_ar8216(priv)) { | ||||||
| 		dev->phy_ptr = priv; | 		dev->phy_ptr = priv; | ||||||
| @@ -2456,6 +2461,7 @@ ar8xxx_phy_config_init(struct phy_device *phydev) | |||||||
| 		dev->eth_mangle_rx = ar8216_mangle_rx; | 		dev->eth_mangle_rx = ar8216_mangle_rx; | ||||||
| 		dev->eth_mangle_tx = ar8216_mangle_tx; | 		dev->eth_mangle_tx = ar8216_mangle_tx; | ||||||
| 	} | 	} | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| @@ -2687,10 +2693,12 @@ ar8xxx_phy_detach(struct phy_device *phydev) | |||||||
| 	if (!dev) | 	if (!dev) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
|  | #ifdef CONFIG_ETHERNET_PACKET_MANGLE | ||||||
| 	dev->phy_ptr = NULL; | 	dev->phy_ptr = NULL; | ||||||
| 	dev->priv_flags &= ~IFF_NO_IP_ALIGN; | 	dev->priv_flags &= ~IFF_NO_IP_ALIGN; | ||||||
| 	dev->eth_mangle_rx = NULL; | 	dev->eth_mangle_rx = NULL; | ||||||
| 	dev->eth_mangle_tx = NULL; | 	dev->eth_mangle_tx = NULL; | ||||||
|  | #endif | ||||||
| } | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
|   | |||||||
							
								
								
									
										196
									
								
								target/linux/generic/hack-5.10/204-module_strip.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								target/linux/generic/hack-5.10/204-module_strip.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,196 @@ | |||||||
|  | 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 | ||||||
|  | @@ -161,6 +161,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) | ||||||
|  | @@ -230,12 +231,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		\ | ||||||
|  | @@ -262,7 +263,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)					\ | ||||||
|  |  	MODULE_INFO(version, _version);					\ | ||||||
|  | @@ -285,7 +288,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) | ||||||
|  |   | ||||||
|  |  #define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, #ns) | ||||||
|  |   | ||||||
|  | --- a/include/linux/moduleparam.h | ||||||
|  | +++ b/include/linux/moduleparam.h | ||||||
|  | @@ -20,6 +20,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 | ||||||
|  | + | ||||||
|  |  #define __MODULE_INFO(tag, name, info)					  \ | ||||||
|  |  static const char __UNIQUE_ID(name)[]					  \ | ||||||
|  |    __used __section(".modinfo") __attribute__((unused, aligned(1)))	  \ | ||||||
|  | @@ -31,7 +41,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 | ||||||
|  | @@ -2327,6 +2327,13 @@ config UNUSED_KSYMS_WHITELIST | ||||||
|  |  	  one per line. The path can be absolute, or relative to the kernel | ||||||
|  |  	  source tree. | ||||||
|  |   | ||||||
|  | +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 | ||||||
|  | @@ -3144,9 +3144,11 @@ static int setup_load_info(struct load_i | ||||||
|  |   | ||||||
|  |  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; | ||||||
|  |   | ||||||
|  | @@ -3167,6 +3169,7 @@ static int check_modinfo(struct module * | ||||||
|  |  				mod->name); | ||||||
|  |  		add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK); | ||||||
|  |  	} | ||||||
|  | +#endif | ||||||
|  |   | ||||||
|  |  	check_modinfo_retpoline(mod, info); | ||||||
|  |   | ||||||
|  | --- a/scripts/mod/modpost.c | ||||||
|  | +++ b/scripts/mod/modpost.c | ||||||
|  | @@ -2037,7 +2037,9 @@ static void read_symbols(const char *mod | ||||||
|  |  		symname = remove_dot(info.strtab + sym->st_name); | ||||||
|  |   | ||||||
|  |  		handle_symbol(mod, &info, sym, symname); | ||||||
|  | +#ifndef CONFIG_MODULE_STRIPPED | ||||||
|  |  		handle_moddevtable(mod, &info, sym, symname); | ||||||
|  | +#endif | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { | ||||||
|  | @@ -2250,8 +2252,10 @@ static void add_header(struct buffer *b, | ||||||
|  |  	buf_printf(b, "\n"); | ||||||
|  |  	buf_printf(b, "BUILD_SALT;\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, "__section(\".gnu.linkonce.this_module\") = {\n"); | ||||||
|  | @@ -2268,8 +2272,10 @@ 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 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /* Cannot check for assembler */ | ||||||
|  | @@ -2282,8 +2288,10 @@ static void add_retpoline(struct buffer | ||||||
|  |   | ||||||
|  |  static void add_staging_flag(struct buffer *b, const char *name) | ||||||
|  |  { | ||||||
|  | +#ifndef CONFIG_MODULE_STRIPPED | ||||||
|  |  	if (strstarts(name, "drivers/staging")) | ||||||
|  |  		buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n"); | ||||||
|  | +#endif | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /** | ||||||
|  | @@ -2367,11 +2375,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_buf(struct buffer *b, const char *fname) | ||||||
|  | @@ -2643,7 +2653,9 @@ int main(int argc, char **argv) | ||||||
|  |  		add_staging_flag(&buf, mod->name); | ||||||
|  |  		err |= add_versions(&buf, mod); | ||||||
|  |  		add_depends(&buf, mod); | ||||||
|  | +#ifndef CONFIG_MODULE_STRIPPED | ||||||
|  |  		add_moddevtable(&buf, mod); | ||||||
|  | +#endif | ||||||
|  |  		add_srcversion(&buf, mod); | ||||||
|  |   | ||||||
|  |  		sprintf(fname, "%s.mod.c", mod->name); | ||||||
							
								
								
									
										3053
									
								
								target/linux/generic/hack-5.10/210-darwin_scripts_include.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3053
									
								
								target/linux/generic/hack-5.10/210-darwin_scripts_include.patch
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | From e44fc2af1ddc452b6659d08c16973d65c73b7d0a Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> | ||||||
|  | Date: Wed, 5 Feb 2020 18:36:43 +0000 | ||||||
|  | Subject: [PATCH] file2alias: build on macos | ||||||
|  |  | ||||||
|  | Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> | ||||||
|  | --- | ||||||
|  |  scripts/mod/file2alias.c | 3 +++ | ||||||
|  |  1 file changed, 3 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/scripts/mod/file2alias.c | ||||||
|  | +++ b/scripts/mod/file2alias.c | ||||||
|  | @@ -38,6 +38,9 @@ typedef struct { | ||||||
|  |  	__u8 b[16]; | ||||||
|  |  } guid_t; | ||||||
|  |   | ||||||
|  | +#ifdef __APPLE__ | ||||||
|  | +#define uuid_t compat_uuid_t | ||||||
|  | +#endif | ||||||
|  |  /* backwards compatibility, don't use in new code */ | ||||||
|  |  typedef struct { | ||||||
|  |  	__u8 b[16]; | ||||||
							
								
								
									
										110
									
								
								target/linux/generic/hack-5.10/212-tools_portability.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								target/linux/generic/hack-5.10/212-tools_portability.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | |||||||
|  | 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: fix portability of some includes files in tools/ used on the host | ||||||
|  |  | ||||||
|  | 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,26 @@ | ||||||
|  | +#ifndef __LINUX_TYPES_H | ||||||
|  | +#define __LINUX_TYPES_H | ||||||
|  | + | ||||||
|  | +#include <stdint.h> | ||||||
|  | + | ||||||
|  | +typedef int8_t __s8; | ||||||
|  | +typedef uint8_t __u8; | ||||||
|  | +typedef uint8_t __be8; | ||||||
|  | +typedef uint8_t __le8; | ||||||
|  | + | ||||||
|  | +typedef int16_t __s16; | ||||||
|  | +typedef uint16_t __u16; | ||||||
|  | +typedef uint16_t __be16; | ||||||
|  | +typedef uint16_t __le16; | ||||||
|  | + | ||||||
|  | +typedef int32_t __s32; | ||||||
|  | +typedef uint32_t __u32; | ||||||
|  | +typedef uint32_t __be32; | ||||||
|  | +typedef uint32_t __le32; | ||||||
|  | + | ||||||
|  | +typedef int64_t __s64; | ||||||
|  | +typedef uint64_t __u64; | ||||||
|  | +typedef uint64_t __be64; | ||||||
|  | +typedef uint64_t __le64; | ||||||
|  | + | ||||||
|  | +#endif | ||||||
|  | --- a/tools/include/linux/types.h | ||||||
|  | +++ b/tools/include/linux/types.h | ||||||
|  | @@ -7,8 +7,12 @@ | ||||||
|  |  #include <stdint.h> | ||||||
|  |   | ||||||
|  |  #define __SANE_USERSPACE_TYPES__	/* For PPC64, to get LL64 types */ | ||||||
|  | +#ifndef __linux__ | ||||||
|  | +#include <tools/linux_types.h> | ||||||
|  | +#else | ||||||
|  |  #include <asm/types.h> | ||||||
|  |  #include <asm/posix_types.h> | ||||||
|  | +#endif | ||||||
|  |   | ||||||
|  |  struct page; | ||||||
|  |  struct kmem_cache; | ||||||
|  | --- a/tools/perf/pmu-events/jevents.c | ||||||
|  | +++ b/tools/perf/pmu-events/jevents.c | ||||||
|  | @@ -1,4 +1,6 @@ | ||||||
|  | +#ifdef __linux__ | ||||||
|  |  #define  _XOPEN_SOURCE 500	/* needed for nftw() */ | ||||||
|  | +#endif | ||||||
|  |  #define  _GNU_SOURCE		/* needed for asprintf() */ | ||||||
|  |   | ||||||
|  |  /* Parse event JSON files */ | ||||||
|  | @@ -35,6 +37,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,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 | ||||||
|  | @@ -121,7 +121,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)]) | ||||||
|  |   | ||||||
							
								
								
									
										120
									
								
								target/linux/generic/hack-5.10/220-gc_sections.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								target/linux/generic/hack-5.10/220-gc_sections.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,120 @@ | |||||||
|  | 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> | ||||||
|  | --- | ||||||
|  | --- a/arch/arm/Kconfig | ||||||
|  | +++ b/arch/arm/Kconfig | ||||||
|  | @@ -113,6 +113,7 @@ config ARM | ||||||
|  |  	select HAVE_UID16 | ||||||
|  |  	select HAVE_VIRT_CPU_ACCOUNTING_GEN | ||||||
|  |  	select IRQ_FORCED_THREADING | ||||||
|  | +	select HAVE_LD_DEAD_CODE_DATA_ELIMINATION | ||||||
|  |  	select MODULES_USE_ELF_REL | ||||||
|  |  	select NEED_DMA_MAP_STATE | ||||||
|  |  	select OF_EARLY_FLATTREE if OF | ||||||
|  | --- a/arch/arm/boot/compressed/Makefile | ||||||
|  | +++ b/arch/arm/boot/compressed/Makefile | ||||||
|  | @@ -98,6 +98,7 @@ $(foreach o, $(libfdt_objs) atags_to_fdt | ||||||
|  |  ifdef building_out_of_srctree | ||||||
|  |  $(shell rm -f $(addprefix $(obj)/, fdt_rw.c fdt_ro.c fdt_wip.c fdt.c)) | ||||||
|  |  endif | ||||||
|  | +KBUILD_CFLAGS_KERNEL := $(patsubst -f%-sections,,$(KBUILD_CFLAGS_KERNEL)) | ||||||
|  |   | ||||||
|  |  targets       := vmlinux vmlinux.lds piggy_data piggy.o \ | ||||||
|  |  		 lib1funcs.o ashldi3.o bswapsdi2.o \ | ||||||
|  | --- a/arch/arm/kernel/vmlinux.lds.S | ||||||
|  | +++ b/arch/arm/kernel/vmlinux.lds.S | ||||||
|  | @@ -100,24 +100,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 = .; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | --- a/arch/arm/include/asm/vmlinux.lds.h | ||||||
|  | +++ b/arch/arm/include/asm/vmlinux.lds.h | ||||||
|  | @@ -23,19 +23,19 @@ | ||||||
|  |  #define ARM_MMU_DISCARD(x) | ||||||
|  |  #else | ||||||
|  |  #define ARM_MMU_KEEP(x) | ||||||
|  | -#define ARM_MMU_DISCARD(x)	x | ||||||
|  | +#define ARM_MMU_DISCARD(x)	KEEP(x) | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  |  #define PROC_INFO							\ | ||||||
|  |  		. = ALIGN(4);						\ | ||||||
|  |  		__proc_info_begin = .;					\ | ||||||
|  | -		*(.proc.info.init)					\ | ||||||
|  | +		KEEP(*(.proc.info.init))				\ | ||||||
|  |  		__proc_info_end = .; | ||||||
|  |   | ||||||
|  |  #define IDMAP_TEXT							\ | ||||||
|  |  		ALIGN_FUNCTION();					\ | ||||||
|  |  		__idmap_text_start = .;					\ | ||||||
|  | -		*(.idmap.text)						\ | ||||||
|  | +		KEEP(*(.idmap.text))					\ | ||||||
|  |  		__idmap_text_end = .;					\ | ||||||
|  |   | ||||||
|  |  #define ARM_DISCARD							\ | ||||||
|  | @@ -96,12 +96,12 @@ | ||||||
|  |  	. = 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 = .;					\ | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | @@ -112,14 +112,14 @@ | ||||||
|  |  #define ARM_VECTORS							\ | ||||||
|  |  	__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 = .;						\ | ||||||
							
								
								
									
										102
									
								
								target/linux/generic/hack-5.10/221-module_exports.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								target/linux/generic/hack-5.10/221-module_exports.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | |||||||
|  | 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 | ||||||
|  | @@ -81,6 +81,16 @@ | ||||||
|  |  #define RO_EXCEPTION_TABLE | ||||||
|  |  #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 | ||||||
|  | + | ||||||
|  |  /* Align . to a 8 byte boundary equals to maximum function alignment. */ | ||||||
|  |  #define ALIGN_FUNCTION()  . = ALIGN(8) | ||||||
|  |   | ||||||
|  | @@ -470,14 +480,14 @@ | ||||||
|  |  	/* Kernel symbol table: Normal symbols */			\ | ||||||
|  |  	__ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {		\ | ||||||
|  |  		__start___ksymtab = .;					\ | ||||||
|  | -		KEEP(*(SORT(___ksymtab+*)))				\ | ||||||
|  | +		SYMTAB_KEEP						\ | ||||||
|  |  		__stop___ksymtab = .;					\ | ||||||
|  |  	}								\ | ||||||
|  |  									\ | ||||||
|  |  	/* Kernel symbol table: GPL-only symbols */			\ | ||||||
|  |  	__ksymtab_gpl     : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) {	\ | ||||||
|  |  		__start___ksymtab_gpl = .;				\ | ||||||
|  | -		KEEP(*(SORT(___ksymtab_gpl+*)))				\ | ||||||
|  | +		SYMTAB_KEEP_GPL						\ | ||||||
|  |  		__stop___ksymtab_gpl = .;				\ | ||||||
|  |  	}								\ | ||||||
|  |  									\ | ||||||
|  | @@ -539,7 +549,7 @@ | ||||||
|  |  									\ | ||||||
|  |  	/* Kernel symbol table: strings */				\ | ||||||
|  |          __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {	\ | ||||||
|  | -		*(__ksymtab_strings)					\ | ||||||
|  | +		*(__ksymtab_strings+*)					\ | ||||||
|  |  	}								\ | ||||||
|  |  									\ | ||||||
|  |  	/* __*init sections */						\ | ||||||
|  | @@ -1008,6 +1018,8 @@ | ||||||
|  |   | ||||||
|  |  #define COMMON_DISCARDS							\ | ||||||
|  |  	SANITIZER_DISCARDS						\ | ||||||
|  | +	SYMTAB_DISCARD							\ | ||||||
|  | +	SYMTAB_DISCARD_GPL						\ | ||||||
|  |  	*(.discard)							\ | ||||||
|  |  	*(.discard.*)							\ | ||||||
|  |  	*(.modinfo)							\ | ||||||
|  | --- a/include/linux/export.h | ||||||
|  | +++ b/include/linux/export.h | ||||||
|  | @@ -82,6 +82,12 @@ struct kernel_symbol { | ||||||
|  |   | ||||||
|  |  #else | ||||||
|  |   | ||||||
|  | +#ifdef MODULE | ||||||
|  | +#define __EXPORT_SUFFIX(sym) | ||||||
|  | +#else | ||||||
|  | +#define __EXPORT_SUFFIX(sym) "+" #sym | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  |  /* | ||||||
|  |   * For every exported symbol, do the following: | ||||||
|  |   * | ||||||
|  | @@ -99,7 +105,7 @@ struct kernel_symbol { | ||||||
|  |  	extern const char __kstrtab_##sym[];					\ | ||||||
|  |  	extern const char __kstrtabns_##sym[];					\ | ||||||
|  |  	__CRC_SYMBOL(sym, sec);							\ | ||||||
|  | -	asm("	.section \"__ksymtab_strings\",\"aMS\",%progbits,1	\n"	\ | ||||||
|  | +	asm("	.section \"__ksymtab_strings" __EXPORT_SUFFIX(sym) "\",\"aMS\",%progbits,1	\n"	\ | ||||||
|  |  	    "__kstrtab_" #sym ":					\n"	\ | ||||||
|  |  	    "	.asciz 	\"" #sym "\"					\n"	\ | ||||||
|  |  	    "__kstrtabns_" #sym ":					\n"	\ | ||||||
|  | --- a/scripts/Makefile.build | ||||||
|  | +++ b/scripts/Makefile.build | ||||||
|  | @@ -366,7 +366,7 @@ targets += $(lib-y) $(always-y) $(MAKECM | ||||||
|  |  # 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,34 @@ | |||||||
|  | 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 +- | ||||||
|  |  usr/gen_initramfs_list.sh | 10 +++++----- | ||||||
|  |  3 files changed, 7 insertions(+), 6 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/lib/decompress.c | ||||||
|  | +++ b/lib/decompress.c | ||||||
|  | @@ -53,6 +53,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 | ||||||
|  | @@ -370,7 +370,7 @@ quiet_cmd_bzip2 = BZIP2   $@ | ||||||
|  |  # --------------------------------------------------------------------------- | ||||||
|  |   | ||||||
|  |  quiet_cmd_lzma = LZMA    $@ | ||||||
|  | -      cmd_lzma = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@ | ||||||
|  | +      cmd_lzma = { cat $(real-prereqs) | $(LZMA) e -d20 -lc1 -lp2 -pb2 -eos -si -so; $(size_append); } > $@ | ||||||
|  |   | ||||||
|  |  quiet_cmd_lzo = LZO     $@ | ||||||
|  |        cmd_lzo = { cat $(real-prereqs) | $(KLZOP) -9; $(size_append); } > $@ | ||||||
							
								
								
									
										27
									
								
								target/linux/generic/hack-5.10/250-netfilter_depends.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								target/linux/generic/hack-5.10/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 | ||||||
|  | @@ -228,7 +228,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 | ||||||
|  | @@ -1072,7 +1071,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 | ||||||
							
								
								
									
										199
									
								
								target/linux/generic/hack-5.10/251-kconfig.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								target/linux/generic/hack-5.10/251-kconfig.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,199 @@ | |||||||
|  | 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_SKCIPHER | ||||||
|  | -	tristate | ||||||
|  | +	tristate "SKCIPHER" | ||||||
|  |  	select CRYPTO_SKCIPHER2 | ||||||
|  |  	select CRYPTO_ALGAPI | ||||||
|  |   | ||||||
|  | @@ -63,7 +63,7 @@ config CRYPTO_SKCIPHER2 | ||||||
|  |  	select CRYPTO_RNG2 | ||||||
|  |   | ||||||
|  |  config CRYPTO_HASH | ||||||
|  | -	tristate | ||||||
|  | +	tristate "HASH" | ||||||
|  |  	select CRYPTO_HASH2 | ||||||
|  |  	select CRYPTO_ALGAPI | ||||||
|  |   | ||||||
|  | @@ -72,7 +72,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 | ||||||
|  | @@ -16,6 +16,7 @@ if BCMA | ||||||
|  |  # Support for Block-I/O. SELECT this from the driver that needs it. | ||||||
|  |  config BCMA_BLOCKIO | ||||||
|  |  	bool | ||||||
|  | +	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 | ||||||
|  | @@ -419,16 +419,16 @@ config BCH_CONST_T | ||||||
|  |  # Textsearch support is select'ed if needed | ||||||
|  |  # | ||||||
|  |  config TEXTSEARCH | ||||||
|  | -	bool | ||||||
|  | +	bool "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 | ||||||
|  | @@ -11,7 +11,7 @@ config NETFILTER_INGRESS | ||||||
|  |  	  infrastructure. | ||||||
|  |   | ||||||
|  |  config NETFILTER_NETLINK | ||||||
|  | -	tristate | ||||||
|  | +	tristate "Netfilter NFNETLINK interface" | ||||||
|  |   | ||||||
|  |  config NETFILTER_FAMILY_BRIDGE | ||||||
|  |  	bool | ||||||
|  | --- a/net/wireless/Kconfig | ||||||
|  | +++ b/net/wireless/Kconfig | ||||||
|  | @@ -1,6 +1,6 @@ | ||||||
|  |  # SPDX-License-Identifier: GPL-2.0-only | ||||||
|  |  config WIRELESS_EXT | ||||||
|  | -	bool | ||||||
|  | +	bool "Wireless extensions" | ||||||
|  |   | ||||||
|  |  config WEXT_CORE | ||||||
|  |  	def_bool y | ||||||
|  | @@ -12,10 +12,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" | ||||||
|  | @@ -204,7 +204,7 @@ config CFG80211_WEXT_EXPORT | ||||||
|  |  endif # CFG80211 | ||||||
|  |   | ||||||
|  |  config LIB80211 | ||||||
|  | -	tristate | ||||||
|  | +	tristate "LIB80211" | ||||||
|  |  	default n | ||||||
|  |  	help | ||||||
|  |  	  This options enables a library of common routines used | ||||||
|  | @@ -213,17 +213,17 @@ config LIB80211 | ||||||
|  |  	  Drivers should select this themselves if needed. | ||||||
|  |   | ||||||
|  |  config LIB80211_CRYPT_WEP | ||||||
|  | -	tristate | ||||||
|  | +	tristate "LIB80211_CRYPT_WEP" | ||||||
|  |  	select CRYPTO_LIB_ARC4 | ||||||
|  |   | ||||||
|  |  config LIB80211_CRYPT_CCMP | ||||||
|  | -	tristate | ||||||
|  | +	tristate "LIB80211_CRYPT_CCMP" | ||||||
|  |  	select CRYPTO | ||||||
|  |  	select CRYPTO_AES | ||||||
|  |  	select CRYPTO_CCM | ||||||
|  |   | ||||||
|  |  config LIB80211_CRYPT_TKIP | ||||||
|  | -	tristate | ||||||
|  | +	tristate "LIB80211_CRYPT_TKIP" | ||||||
|  |  	select CRYPTO_LIB_ARC4 | ||||||
|  |   | ||||||
|  |  config LIB80211_DEBUG | ||||||
|  | --- a/sound/core/Kconfig | ||||||
|  | +++ b/sound/core/Kconfig | ||||||
|  | @@ -17,7 +17,7 @@ config SND_DMAENGINE_PCM | ||||||
|  |  	tristate | ||||||
|  |   | ||||||
|  |  config SND_HWDEP | ||||||
|  | -	tristate | ||||||
|  | +	tristate "Sound hardware support" | ||||||
|  |   | ||||||
|  |  config SND_SEQ_DEVICE | ||||||
|  |  	tristate | ||||||
|  | @@ -27,7 +27,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 | ||||||
							
								
								
									
										135
									
								
								target/linux/generic/hack-5.10/259-regmap_dynamic.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								target/linux/generic/hack-5.10/259-regmap_dynamic.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,135 @@ | |||||||
|  | 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 || REGMAP_SOUNDWIRE || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM) | ||||||
|  |  	select IRQ_DOMAIN if REGMAP_IRQ | ||||||
|  | -	bool | ||||||
|  | +	tristate | ||||||
|  |   | ||||||
|  |  config REGCACHE_COMPRESSED | ||||||
|  |  	select LZO_COMPRESS | ||||||
|  | @@ -14,46 +13,59 @@ config REGCACHE_COMPRESSED | ||||||
|  |  	bool | ||||||
|  |   | ||||||
|  |  config REGMAP_AC97 | ||||||
|  | +	select REGMAP | ||||||
|  |  	tristate | ||||||
|  |   | ||||||
|  |  config REGMAP_I2C | ||||||
|  |  	tristate | ||||||
|  | +	select REGMAP | ||||||
|  |  	depends on I2C | ||||||
|  |   | ||||||
|  |  config REGMAP_SLIMBUS | ||||||
|  |  	tristate | ||||||
|  | +	select REGMAP | ||||||
|  |  	depends on SLIMBUS | ||||||
|  |   | ||||||
|  |  config REGMAP_SPI | ||||||
|  |  	tristate | ||||||
|  | +	select REGMAP | ||||||
|  | +	depends on SPI_MASTER | ||||||
|  |  	depends on SPI | ||||||
|  |   | ||||||
|  |  config REGMAP_SPMI | ||||||
|  |  	tristate | ||||||
|  | +	select REGMAP | ||||||
|  |  	depends on SPMI | ||||||
|  |   | ||||||
|  |  config REGMAP_W1 | ||||||
|  |  	tristate | ||||||
|  | +	select REGMAP | ||||||
|  |  	depends on W1 | ||||||
|  |   | ||||||
|  |  config REGMAP_MMIO | ||||||
|  |  	tristate | ||||||
|  | +	select REGMAP | ||||||
|  |   | ||||||
|  |  config REGMAP_IRQ | ||||||
|  |  	bool | ||||||
|  | +	select REGMAP | ||||||
|  |   | ||||||
|  |  config REGMAP_SOUNDWIRE | ||||||
|  |  	tristate | ||||||
|  | +	select REGMAP | ||||||
|  |  	depends on SOUNDWIRE | ||||||
|  |   | ||||||
|  |  config REGMAP_SCCB | ||||||
|  |  	tristate | ||||||
|  | +	select REGMAP | ||||||
|  |  	depends on I2C | ||||||
|  |   | ||||||
|  |  config REGMAP_I3C | ||||||
|  |  	tristate | ||||||
|  | +	select REGMAP | ||||||
|  |  	depends on I3C | ||||||
|  |   | ||||||
|  |  config REGMAP_SPI_AVMM | ||||||
|  |  	tristate | ||||||
|  | +	select REGMAP | ||||||
|  |  	depends on SPI | ||||||
|  | --- 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_SLIMBUS) += regmap-slimbus.o | ||||||
|  | --- a/drivers/base/regmap/regmap.c | ||||||
|  | +++ b/drivers/base/regmap/regmap.c | ||||||
|  | @@ -9,6 +9,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/property.h> | ||||||
|  | @@ -3296,3 +3297,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 | ||||||
|  | @@ -179,7 +179,7 @@ struct reg_sequence { | ||||||
|  |  	__ret ?: __tmp; \ | ||||||
|  |  }) | ||||||
|  |   | ||||||
|  | -#ifdef CONFIG_REGMAP | ||||||
|  | +#if IS_REACHABLE(CONFIG_REGMAP) | ||||||
|  |   | ||||||
|  |  enum regmap_endian { | ||||||
|  |  	/* Unspecified -> 0 -> Backwards compatible default */ | ||||||
| @@ -0,0 +1,52 @@ | |||||||
|  | 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 | ||||||
|  | @@ -120,13 +120,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_SKCIPHER2 | ||||||
|  | -	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_SKCIPHER2 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" | ||||||
|  | --- a/crypto/algboss.c | ||||||
|  | +++ b/crypto/algboss.c | ||||||
|  | @@ -230,8 +230,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; | ||||||
|  |   | ||||||
							
								
								
									
										15
									
								
								target/linux/generic/hack-5.10/261-lib-arc4-unhide.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								target/linux/generic/hack-5.10/261-lib-arc4-unhide.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | This makes it possible to select CONFIG_CRYPTO_LIB_ARC4 directly. We  | ||||||
|  | need this to be able to compile this into the kernel and make use of it  | ||||||
|  | from backports. | ||||||
|  |  | ||||||
|  | --- a/lib/crypto/Kconfig | ||||||
|  | +++ b/lib/crypto/Kconfig | ||||||
|  | @@ -6,7 +6,7 @@ config CRYPTO_LIB_AES | ||||||
|  |  	tristate | ||||||
|  |   | ||||||
|  |  config CRYPTO_LIB_ARC4 | ||||||
|  | -	tristate | ||||||
|  | +	tristate "ARC4 cipher library" | ||||||
|  |   | ||||||
|  |  config CRYPTO_ARCH_HAVE_LIB_BLAKE2S | ||||||
|  |  	tristate | ||||||
							
								
								
									
										84
									
								
								target/linux/generic/hack-5.10/280-rfkill-stubs.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								target/linux/generic/hack-5.10/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 | ||||||
|  | @@ -2,7 +2,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 | ||||||
|  | @@ -14,19 +18,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 | ||||||
|  | @@ -5,5 +5,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,64 @@ | |||||||
|  | From: Ben Menchaca <ben.menchaca@qca.qualcomm.com> | ||||||
|  | Date: Fri, 7 Jun 2013 18:35:22 -0500 | ||||||
|  | Subject: MIPS: r4k_cache: use more efficient cache blast | ||||||
|  |  | ||||||
|  | Optimize the compiler output for larger cache blast cases that are | ||||||
|  | common for DMA-based networking. | ||||||
|  |  | ||||||
|  | Signed-off-by: Ben Menchaca <ben.menchaca@qca.qualcomm.com> | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  | --- a/arch/mips/include/asm/r4kcache.h | ||||||
|  | +++ b/arch/mips/include/asm/r4kcache.h | ||||||
|  | @@ -296,14 +296,46 @@ static inline void prot##extra##blast_## | ||||||
|  |  						    unsigned long end)	\ | ||||||
|  |  {									\ | ||||||
|  |  	unsigned long lsize = cpu_##desc##_line_size();			\ | ||||||
|  | +	unsigned long lsize_2 = lsize * 2;				\ | ||||||
|  | +	unsigned long lsize_3 = lsize * 3;				\ | ||||||
|  | +	unsigned long lsize_4 = lsize * 4;				\ | ||||||
|  | +	unsigned long lsize_5 = lsize * 5;				\ | ||||||
|  | +	unsigned long lsize_6 = lsize * 6;				\ | ||||||
|  | +	unsigned long lsize_7 = lsize * 7;				\ | ||||||
|  | +	unsigned long lsize_8 = lsize * 8;				\ | ||||||
|  |  	unsigned long addr = start & ~(lsize - 1);			\ | ||||||
|  | -	unsigned long aend = (end - 1) & ~(lsize - 1);			\ | ||||||
|  | +	unsigned long aend = (end + lsize - 1) & ~(lsize - 1);		\ | ||||||
|  | +	int lines = (aend - addr) / lsize;				\ | ||||||
|  |  									\ | ||||||
|  | -	while (1) {							\ | ||||||
|  | +	while (lines >= 8) {						\ | ||||||
|  | +		prot##cache_op(hitop, addr);				\ | ||||||
|  | +		prot##cache_op(hitop, addr + lsize);			\ | ||||||
|  | +		prot##cache_op(hitop, addr + lsize_2);			\ | ||||||
|  | +		prot##cache_op(hitop, addr + lsize_3);			\ | ||||||
|  | +		prot##cache_op(hitop, addr + lsize_4);			\ | ||||||
|  | +		prot##cache_op(hitop, addr + lsize_5);			\ | ||||||
|  | +		prot##cache_op(hitop, addr + lsize_6);			\ | ||||||
|  | +		prot##cache_op(hitop, addr + lsize_7);			\ | ||||||
|  | +		addr += lsize_8;					\ | ||||||
|  | +		lines -= 8;						\ | ||||||
|  | +	}								\ | ||||||
|  | +									\ | ||||||
|  | +	if (lines & 0x4) {						\ | ||||||
|  | +		prot##cache_op(hitop, addr);				\ | ||||||
|  | +		prot##cache_op(hitop, addr + lsize);			\ | ||||||
|  | +		prot##cache_op(hitop, addr + lsize_2);			\ | ||||||
|  | +		prot##cache_op(hitop, addr + lsize_3);			\ | ||||||
|  | +		addr += lsize_4;					\ | ||||||
|  | +	}								\ | ||||||
|  | +									\ | ||||||
|  | +	if (lines & 0x2) {						\ | ||||||
|  | +		prot##cache_op(hitop, addr);				\ | ||||||
|  | +		prot##cache_op(hitop, addr + lsize);			\ | ||||||
|  | +		addr += lsize_2;					\ | ||||||
|  | +	}								\ | ||||||
|  | +									\ | ||||||
|  | +	if (lines & 0x1) {						\ | ||||||
|  |  		prot##cache_op(hitop, addr);				\ | ||||||
|  | -		if (addr == aend)					\ | ||||||
|  | -			break;						\ | ||||||
|  | -		addr += lsize;						\ | ||||||
|  |  	}								\ | ||||||
|  |  } | ||||||
|  |   | ||||||
| @@ -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 | ||||||
|  | @@ -1162,6 +1162,10 @@ config MIPS_MSC | ||||||
|  |  config SYNC_R4K | ||||||
|  |  	bool | ||||||
|  |   | ||||||
|  | +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 /* CONFIG_BOOT_RAW */ | ||||||
|  |   | ||||||
|  | +#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 | ||||||
|  | @@ -61,19 +61,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 | ||||||
|  | - | ||||||
|  |  ifdef CONFIG_CPU_LITTLE_ENDIAN | ||||||
|  |  KBUILD_CFLAGS	+= -mlittle-endian | ||||||
|  |  KBUILD_LDFLAGS	+= -EL | ||||||
							
								
								
									
										1037
									
								
								target/linux/generic/hack-5.10/531-debloat_lzma.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1037
									
								
								target/linux/generic/hack-5.10/531-debloat_lzma.patch
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,82 @@ | |||||||
|  | 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> | ||||||
|  | [add disable_eap_hack sysfs attribute] | ||||||
|  | Signed-off-by: Etienne Champetier <champetier.etienne@gmail.com> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/net/bridge/br_input.c | ||||||
|  | +++ b/net/bridge/br_input.c | ||||||
|  | @@ -107,10 +107,14 @@ int br_handle_frame_finish(struct net *n | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	BR_INPUT_SKB_CB(skb)->brdev = br->dev; | ||||||
|  | + | ||||||
|  | +	if (skb->protocol == htons(ETH_P_PAE) && !br->disable_eap_hack) | ||||||
|  | +		return br_pass_frame_up(skb); | ||||||
|  | + | ||||||
|  |  	if (state == BR_STATE_LEARNING) | ||||||
|  |  		goto drop; | ||||||
|  |   | ||||||
|  | -	BR_INPUT_SKB_CB(skb)->brdev = br->dev; | ||||||
|  |  	BR_INPUT_SKB_CB(skb)->src_port_isolated = !!(p->flags & BR_ISOLATED); | ||||||
|  |   | ||||||
|  |  	if (IS_ENABLED(CONFIG_INET) && | ||||||
|  | --- a/net/bridge/br_private.h | ||||||
|  | +++ b/net/bridge/br_private.h | ||||||
|  | @@ -404,6 +404,8 @@ struct net_bridge { | ||||||
|  |  	u16				group_fwd_mask; | ||||||
|  |  	u16				group_fwd_mask_required; | ||||||
|  |   | ||||||
|  | +	bool				disable_eap_hack; | ||||||
|  | + | ||||||
|  |  	/* STP */ | ||||||
|  |  	bridge_id			designated_root; | ||||||
|  |  	bridge_id			bridge_id; | ||||||
|  | --- a/net/bridge/br_sysfs_br.c | ||||||
|  | +++ b/net/bridge/br_sysfs_br.c | ||||||
|  | @@ -164,6 +164,30 @@ static ssize_t group_fwd_mask_store(stru | ||||||
|  |  } | ||||||
|  |  static DEVICE_ATTR_RW(group_fwd_mask); | ||||||
|  |   | ||||||
|  | +static ssize_t disable_eap_hack_show(struct device *d, | ||||||
|  | +				   struct device_attribute *attr, | ||||||
|  | +				   char *buf) | ||||||
|  | +{ | ||||||
|  | +	struct net_bridge *br = to_bridge(d); | ||||||
|  | +	return sprintf(buf, "%u\n", br->disable_eap_hack); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int set_disable_eap_hack(struct net_bridge *br, unsigned long val) | ||||||
|  | +{ | ||||||
|  | +	br->disable_eap_hack = !!val; | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static ssize_t disable_eap_hack_store(struct device *d, | ||||||
|  | +				    struct device_attribute *attr, | ||||||
|  | +				    const char *buf, | ||||||
|  | +				    size_t len) | ||||||
|  | +{ | ||||||
|  | +	return store_bridge_parm(d, buf, len, set_disable_eap_hack); | ||||||
|  | +} | ||||||
|  | +static DEVICE_ATTR_RW(disable_eap_hack); | ||||||
|  | + | ||||||
|  |  static ssize_t priority_show(struct device *d, struct device_attribute *attr, | ||||||
|  |  			     char *buf) | ||||||
|  |  { | ||||||
|  | @@ -849,6 +873,7 @@ static struct attribute *bridge_attrs[] | ||||||
|  |  	&dev_attr_ageing_time.attr, | ||||||
|  |  	&dev_attr_stp_state.attr, | ||||||
|  |  	&dev_attr_group_fwd_mask.attr, | ||||||
|  | +	&dev_attr_disable_eap_hack.attr, | ||||||
|  |  	&dev_attr_priority.attr, | ||||||
|  |  	&dev_attr_bridge_id.attr, | ||||||
|  |  	&dev_attr_root_id.attr, | ||||||
| @@ -0,0 +1,212 @@ | |||||||
|  | From eda40b8c8c82e0f2789d6bc8bf63846dce2e8f32 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> | ||||||
|  | Date: Sat, 23 Mar 2019 09:29:49 +0000 | ||||||
|  | Subject: [PATCH] netfilter: connmark: introduce set-dscpmark | ||||||
|  |  | ||||||
|  | set-dscpmark is a method of storing the DSCP of an ip packet into | ||||||
|  | conntrack mark.  In combination with a suitable tc filter action | ||||||
|  | (act_ctinfo) DSCP values are able to be stored in the mark on egress and | ||||||
|  | restored on ingress across links that otherwise alter or bleach DSCP. | ||||||
|  |  | ||||||
|  | This is useful for qdiscs such as CAKE which are able to shape according | ||||||
|  | to policies based on DSCP. | ||||||
|  |  | ||||||
|  | Ingress classification is traditionally a challenging task since | ||||||
|  | iptables rules haven't yet run and tc filter/eBPF programs are pre-NAT | ||||||
|  | lookups, hence are unable to see internal IPv4 addresses as used on the | ||||||
|  | typical home masquerading gateway. | ||||||
|  |  | ||||||
|  | x_tables CONNMARK set-dscpmark target solves the problem of storing the | ||||||
|  | DSCP to the conntrack mark in a way suitable for the new act_ctinfo tc | ||||||
|  | action to restore. | ||||||
|  |  | ||||||
|  | The set-dscpmark option accepts 2 parameters, a 32bit 'dscpmask' and a | ||||||
|  | 32bit 'statemask'.  The dscp mask must be 6 contiguous bits and | ||||||
|  | represents the area where the DSCP will be stored in the connmark.  The | ||||||
|  | state mask is a minimum 1 bit length mask that must not overlap with the | ||||||
|  | dscpmask.  It represents a flag which is set when the DSCP has been | ||||||
|  | stored in the conntrack mark. This is useful to implement a 'one shot' | ||||||
|  | iptables based classification where the 'complicated' iptables rules are | ||||||
|  | only run once to classify the connection on initial (egress) packet and | ||||||
|  | subsequent packets are all marked/restored with the same DSCP.  A state | ||||||
|  | mask of zero disables the setting of a status bit/s. | ||||||
|  |  | ||||||
|  | example syntax with a suitably modified iptables user space application: | ||||||
|  |  | ||||||
|  | iptables -A QOS_MARK_eth0 -t mangle -j CONNMARK --set-dscpmark 0xfc000000/0x01000000 | ||||||
|  |  | ||||||
|  | Would store the DSCP in the top 6 bits of the 32bit mark field, and use | ||||||
|  | the LSB of the top byte as the 'DSCP has been stored' marker. | ||||||
|  |  | ||||||
|  | |----0xFC----conntrack mark----000000---| | ||||||
|  | | Bits 31-26 | bit 25 | bit24 |~~~ Bit 0| | ||||||
|  | | DSCP       | unused | flag  |unused   | | ||||||
|  | |-----------------------0x01---000000---| | ||||||
|  |       ^                   ^ | ||||||
|  |       |                   | | ||||||
|  |       ---|             Conditional flag | ||||||
|  |          |             set this when dscp | ||||||
|  | |-ip diffserv-|        stored in mark | ||||||
|  | | 6 bits      | | ||||||
|  | |-------------| | ||||||
|  |  | ||||||
|  | an identically configured tc action to restore looks like: | ||||||
|  |  | ||||||
|  | tc filter show dev eth0 ingress | ||||||
|  | filter parent ffff: protocol all pref 10 u32 chain 0 | ||||||
|  | filter parent ffff: protocol all pref 10 u32 chain 0 fh 800: ht divisor 1 | ||||||
|  | filter parent ffff: protocol all pref 10 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1: not_in_hw | ||||||
|  |   match 00000000/00000000 at 0 | ||||||
|  | 	action order 1: ctinfo zone 0 pipe | ||||||
|  | 	 index 2 ref 1 bind 1 dscp 0xfc000000/0x1000000 | ||||||
|  |  | ||||||
|  | 	action order 2: mirred (Egress Redirect to device ifb4eth0) stolen | ||||||
|  | 	index 1 ref 1 bind 1 | ||||||
|  |  | ||||||
|  | |----0xFC----conntrack mark----000000---| | ||||||
|  | | Bits 31-26 | bit 25 | bit24 |~~~ Bit 0| | ||||||
|  | | DSCP       | unused | flag  |unused   | | ||||||
|  | |-----------------------0x01---000000---| | ||||||
|  |       |                   | | ||||||
|  |       |                   | | ||||||
|  |       ---|             Conditional flag | ||||||
|  |          v             only restore if set | ||||||
|  | |-ip diffserv-| | ||||||
|  | | 6 bits      | | ||||||
|  | |-------------| | ||||||
|  |  | ||||||
|  | Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> | ||||||
|  | --- | ||||||
|  |  include/uapi/linux/netfilter/xt_connmark.h | 10 ++++ | ||||||
|  |  net/netfilter/xt_connmark.c                | 55 ++++++++++++++++++---- | ||||||
|  |  2 files changed, 57 insertions(+), 8 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/include/uapi/linux/netfilter/xt_connmark.h | ||||||
|  | +++ b/include/uapi/linux/netfilter/xt_connmark.h | ||||||
|  | @@ -20,6 +20,11 @@ enum { | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  enum { | ||||||
|  | +	XT_CONNMARK_VALUE =	(1 << 0), | ||||||
|  | +	XT_CONNMARK_DSCP = 	(1 << 1) | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +enum { | ||||||
|  |  	D_SHIFT_LEFT = 0, | ||||||
|  |  	D_SHIFT_RIGHT, | ||||||
|  |  }; | ||||||
|  | @@ -34,6 +39,11 @@ struct xt_connmark_tginfo2 { | ||||||
|  |  	__u8 shift_dir, shift_bits, mode; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +struct xt_connmark_tginfo3 { | ||||||
|  | +	__u32 ctmark, ctmask, nfmask; | ||||||
|  | +	__u8 shift_dir, shift_bits, mode, func; | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  |  struct xt_connmark_mtinfo1 { | ||||||
|  |  	__u32 mark, mask; | ||||||
|  |  	__u8 invert; | ||||||
|  | --- a/net/netfilter/xt_connmark.c | ||||||
|  | +++ b/net/netfilter/xt_connmark.c | ||||||
|  | @@ -24,12 +24,13 @@ MODULE_ALIAS("ipt_connmark"); | ||||||
|  |  MODULE_ALIAS("ip6t_connmark"); | ||||||
|  |   | ||||||
|  |  static unsigned int | ||||||
|  | -connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info) | ||||||
|  | +connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo3 *info) | ||||||
|  |  { | ||||||
|  |  	enum ip_conntrack_info ctinfo; | ||||||
|  |  	u_int32_t new_targetmark; | ||||||
|  |  	struct nf_conn *ct; | ||||||
|  |  	u_int32_t newmark; | ||||||
|  | +	u_int8_t dscp; | ||||||
|  |   | ||||||
|  |  	ct = nf_ct_get(skb, &ctinfo); | ||||||
|  |  	if (ct == NULL) | ||||||
|  | @@ -37,12 +38,24 @@ connmark_tg_shift(struct sk_buff *skb, c | ||||||
|  |   | ||||||
|  |  	switch (info->mode) { | ||||||
|  |  	case XT_CONNMARK_SET: | ||||||
|  | -		newmark = (ct->mark & ~info->ctmask) ^ info->ctmark; | ||||||
|  | -		if (info->shift_dir == D_SHIFT_RIGHT) | ||||||
|  | -			newmark >>= info->shift_bits; | ||||||
|  | -		else | ||||||
|  | -			newmark <<= info->shift_bits; | ||||||
|  | +		newmark = ct->mark; | ||||||
|  | +		if (info->func & XT_CONNMARK_VALUE) { | ||||||
|  | +			newmark = (newmark & ~info->ctmask) ^ info->ctmark; | ||||||
|  | +			if (info->shift_dir == D_SHIFT_RIGHT) | ||||||
|  | +				newmark >>= info->shift_bits; | ||||||
|  | +			else | ||||||
|  | +				newmark <<= info->shift_bits; | ||||||
|  | +		} else if (info->func & XT_CONNMARK_DSCP) { | ||||||
|  | +			if (skb->protocol == htons(ETH_P_IP)) | ||||||
|  | +				dscp = ipv4_get_dsfield(ip_hdr(skb)) >> 2; | ||||||
|  | +			else if (skb->protocol == htons(ETH_P_IPV6)) | ||||||
|  | +				dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2; | ||||||
|  | +			else	/* protocol doesn't have diffserv */ | ||||||
|  | +				break; | ||||||
|  |   | ||||||
|  | +			newmark = (newmark & ~info->ctmark) | | ||||||
|  | +				  (info->ctmask | (dscp << info->shift_bits)); | ||||||
|  | +		} | ||||||
|  |  		if (ct->mark != newmark) { | ||||||
|  |  			ct->mark = newmark; | ||||||
|  |  			nf_conntrack_event_cache(IPCT_MARK, ct); | ||||||
|  | @@ -81,20 +94,36 @@ static unsigned int | ||||||
|  |  connmark_tg(struct sk_buff *skb, const struct xt_action_param *par) | ||||||
|  |  { | ||||||
|  |  	const struct xt_connmark_tginfo1 *info = par->targinfo; | ||||||
|  | -	const struct xt_connmark_tginfo2 info2 = { | ||||||
|  | +	const struct xt_connmark_tginfo3 info3 = { | ||||||
|  |  		.ctmark	= info->ctmark, | ||||||
|  |  		.ctmask	= info->ctmask, | ||||||
|  |  		.nfmask	= info->nfmask, | ||||||
|  |  		.mode	= info->mode, | ||||||
|  | +		.func	= XT_CONNMARK_VALUE | ||||||
|  |  	}; | ||||||
|  |   | ||||||
|  | -	return connmark_tg_shift(skb, &info2); | ||||||
|  | +	return connmark_tg_shift(skb, &info3); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static unsigned int | ||||||
|  |  connmark_tg_v2(struct sk_buff *skb, const struct xt_action_param *par) | ||||||
|  |  { | ||||||
|  |  	const struct xt_connmark_tginfo2 *info = par->targinfo; | ||||||
|  | +	const struct xt_connmark_tginfo3 info3 = { | ||||||
|  | +		.ctmark	= info->ctmark, | ||||||
|  | +		.ctmask	= info->ctmask, | ||||||
|  | +		.nfmask	= info->nfmask, | ||||||
|  | +		.mode	= info->mode, | ||||||
|  | +		.func	= XT_CONNMARK_VALUE | ||||||
|  | +	}; | ||||||
|  | + | ||||||
|  | +	return connmark_tg_shift(skb, &info3); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static unsigned int | ||||||
|  | +connmark_tg_v3(struct sk_buff *skb, const struct xt_action_param *par) | ||||||
|  | +{ | ||||||
|  | +	const struct xt_connmark_tginfo3 *info = par->targinfo; | ||||||
|  |   | ||||||
|  |  	return connmark_tg_shift(skb, info); | ||||||
|  |  } | ||||||
|  | @@ -165,6 +194,16 @@ static struct xt_target connmark_tg_reg[ | ||||||
|  |  		.targetsize     = sizeof(struct xt_connmark_tginfo2), | ||||||
|  |  		.destroy        = connmark_tg_destroy, | ||||||
|  |  		.me             = THIS_MODULE, | ||||||
|  | +	}, | ||||||
|  | +	{ | ||||||
|  | +		.name           = "CONNMARK", | ||||||
|  | +		.revision       = 3, | ||||||
|  | +		.family         = NFPROTO_UNSPEC, | ||||||
|  | +		.checkentry     = connmark_tg_check, | ||||||
|  | +		.target         = connmark_tg_v3, | ||||||
|  | +		.targetsize     = sizeof(struct xt_connmark_tginfo3), | ||||||
|  | +		.destroy        = connmark_tg_destroy, | ||||||
|  | +		.me             = THIS_MODULE, | ||||||
|  |  	} | ||||||
|  |  }; | ||||||
|  |   | ||||||
| @@ -0,0 +1,822 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Tue, 20 Feb 2018 15:56:02 +0100 | ||||||
|  | Subject: [PATCH] netfilter: add xt_OFFLOAD target | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  create mode 100644 net/netfilter/xt_OFFLOAD.c | ||||||
|  |  | ||||||
|  | --- a/net/ipv4/netfilter/Kconfig | ||||||
|  | +++ b/net/ipv4/netfilter/Kconfig | ||||||
|  | @@ -56,8 +56,6 @@ config NF_TABLES_ARP | ||||||
|  |  	help | ||||||
|  |  	  This option enables the ARP support for nf_tables. | ||||||
|  |   | ||||||
|  | -endif # NF_TABLES | ||||||
|  | - | ||||||
|  |  config NF_FLOW_TABLE_IPV4 | ||||||
|  |  	tristate "Netfilter flow table IPv4 module" | ||||||
|  |  	depends on NF_FLOW_TABLE | ||||||
|  | @@ -66,6 +64,8 @@ config NF_FLOW_TABLE_IPV4 | ||||||
|  |   | ||||||
|  |  	  To compile it as a module, choose M here. | ||||||
|  |   | ||||||
|  | +endif # NF_TABLES | ||||||
|  | + | ||||||
|  |  config NF_DUP_IPV4 | ||||||
|  |  	tristate "Netfilter IPv4 packet duplication to alternate destination" | ||||||
|  |  	depends on !NF_CONNTRACK || NF_CONNTRACK | ||||||
|  | --- a/net/ipv6/netfilter/Kconfig | ||||||
|  | +++ b/net/ipv6/netfilter/Kconfig | ||||||
|  | @@ -45,7 +45,6 @@ config NFT_FIB_IPV6 | ||||||
|  |  	  multicast or blackhole. | ||||||
|  |   | ||||||
|  |  endif # NF_TABLES_IPV6 | ||||||
|  | -endif # NF_TABLES | ||||||
|  |   | ||||||
|  |  config NF_FLOW_TABLE_IPV6 | ||||||
|  |  	tristate "Netfilter flow table IPv6 module" | ||||||
|  | @@ -55,6 +54,8 @@ config NF_FLOW_TABLE_IPV6 | ||||||
|  |   | ||||||
|  |  	  To compile it as a module, choose M here. | ||||||
|  |   | ||||||
|  | +endif # NF_TABLES | ||||||
|  | + | ||||||
|  |  config NF_DUP_IPV6 | ||||||
|  |  	tristate "Netfilter IPv6 packet duplication to alternate destination" | ||||||
|  |  	depends on !NF_CONNTRACK || NF_CONNTRACK | ||||||
|  | --- a/net/netfilter/Kconfig | ||||||
|  | +++ b/net/netfilter/Kconfig | ||||||
|  | @@ -683,8 +683,6 @@ config NFT_FIB_NETDEV | ||||||
|  |   | ||||||
|  |  endif # NF_TABLES_NETDEV | ||||||
|  |   | ||||||
|  | -endif # NF_TABLES | ||||||
|  | - | ||||||
|  |  config NF_FLOW_TABLE_INET | ||||||
|  |  	tristate "Netfilter flow table mixed IPv4/IPv6 module" | ||||||
|  |  	depends on NF_FLOW_TABLE | ||||||
|  | @@ -693,11 +691,12 @@ config NF_FLOW_TABLE_INET | ||||||
|  |   | ||||||
|  |  	  To compile it as a module, choose M here. | ||||||
|  |   | ||||||
|  | +endif # NF_TABLES | ||||||
|  | + | ||||||
|  |  config NF_FLOW_TABLE | ||||||
|  |  	tristate "Netfilter flow table module" | ||||||
|  |  	depends on NETFILTER_INGRESS | ||||||
|  |  	depends on NF_CONNTRACK | ||||||
|  | -	depends on NF_TABLES | ||||||
|  |  	help | ||||||
|  |  	  This option adds the flow table core infrastructure. | ||||||
|  |   | ||||||
|  | @@ -977,6 +976,15 @@ config NETFILTER_XT_TARGET_NOTRACK | ||||||
|  |  	depends on NETFILTER_ADVANCED | ||||||
|  |  	select NETFILTER_XT_TARGET_CT | ||||||
|  |   | ||||||
|  | +config NETFILTER_XT_TARGET_FLOWOFFLOAD | ||||||
|  | +	tristate '"FLOWOFFLOAD" target support' | ||||||
|  | +	depends on NF_FLOW_TABLE | ||||||
|  | +	depends on NETFILTER_INGRESS | ||||||
|  | +	help | ||||||
|  | +	  This option adds a `FLOWOFFLOAD' target, which uses the nf_flow_offload | ||||||
|  | +	  module to speed up processing of packets by bypassing the usual | ||||||
|  | +	  netfilter chains | ||||||
|  | + | ||||||
|  |  config NETFILTER_XT_TARGET_RATEEST | ||||||
|  |  	tristate '"RATEEST" target support' | ||||||
|  |  	depends on NETFILTER_ADVANCED | ||||||
|  | --- a/net/netfilter/Makefile | ||||||
|  | +++ b/net/netfilter/Makefile | ||||||
|  | @@ -145,6 +145,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIF | ||||||
|  |  obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o | ||||||
|  |  obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o | ||||||
|  |  obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o | ||||||
|  | +obj-$(CONFIG_NETFILTER_XT_TARGET_FLOWOFFLOAD) += xt_FLOWOFFLOAD.o | ||||||
|  |  obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o | ||||||
|  |  obj-$(CONFIG_NETFILTER_XT_TARGET_HMARK) += xt_HMARK.o | ||||||
|  |  obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/net/netfilter/xt_FLOWOFFLOAD.c | ||||||
|  | @@ -0,0 +1,660 @@ | ||||||
|  | +/* | ||||||
|  | + * Copyright (C) 2018-2021 Felix Fietkau <nbd@nbd.name> | ||||||
|  | + * | ||||||
|  | + * 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. | ||||||
|  | + */ | ||||||
|  | +#include <linux/module.h> | ||||||
|  | +#include <linux/init.h> | ||||||
|  | +#include <linux/netfilter.h> | ||||||
|  | +#include <linux/netfilter/xt_FLOWOFFLOAD.h> | ||||||
|  | +#include <net/ip.h> | ||||||
|  | +#include <net/netfilter/nf_conntrack.h> | ||||||
|  | +#include <net/netfilter/nf_conntrack_extend.h> | ||||||
|  | +#include <net/netfilter/nf_conntrack_helper.h> | ||||||
|  | +#include <net/netfilter/nf_flow_table.h> | ||||||
|  | + | ||||||
|  | +struct xt_flowoffload_hook { | ||||||
|  | +	struct hlist_node list; | ||||||
|  | +	struct nf_hook_ops ops; | ||||||
|  | +	struct net *net; | ||||||
|  | +	bool registered; | ||||||
|  | +	bool used; | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +struct xt_flowoffload_table { | ||||||
|  | +	struct nf_flowtable ft; | ||||||
|  | +	struct hlist_head hooks; | ||||||
|  | +	struct delayed_work work; | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +static DEFINE_SPINLOCK(hooks_lock); | ||||||
|  | + | ||||||
|  | +struct xt_flowoffload_table flowtable[2]; | ||||||
|  | + | ||||||
|  | +static unsigned int | ||||||
|  | +xt_flowoffload_net_hook(void *priv, struct sk_buff *skb, | ||||||
|  | +			const struct nf_hook_state *state) | ||||||
|  | +{ | ||||||
|  | +	struct nf_flowtable *ft = priv; | ||||||
|  | + | ||||||
|  | +	if (!atomic_read(&ft->rhashtable.nelems)) | ||||||
|  | +		return NF_ACCEPT; | ||||||
|  | + | ||||||
|  | +	switch (skb->protocol) { | ||||||
|  | +	case htons(ETH_P_IP): | ||||||
|  | +		return nf_flow_offload_ip_hook(priv, skb, state); | ||||||
|  | +	case htons(ETH_P_IPV6): | ||||||
|  | +		return nf_flow_offload_ipv6_hook(priv, skb, state); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return NF_ACCEPT; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int | ||||||
|  | +xt_flowoffload_create_hook(struct xt_flowoffload_table *table, | ||||||
|  | +			   struct net_device *dev) | ||||||
|  | +{ | ||||||
|  | +	struct xt_flowoffload_hook *hook; | ||||||
|  | +	struct nf_hook_ops *ops; | ||||||
|  | + | ||||||
|  | +	hook = kzalloc(sizeof(*hook), GFP_ATOMIC); | ||||||
|  | +	if (!hook) | ||||||
|  | +		return -ENOMEM; | ||||||
|  | + | ||||||
|  | +	ops = &hook->ops; | ||||||
|  | +	ops->pf = NFPROTO_NETDEV; | ||||||
|  | +	ops->hooknum = NF_NETDEV_INGRESS; | ||||||
|  | +	ops->priority = 10; | ||||||
|  | +	ops->priv = &table->ft; | ||||||
|  | +	ops->hook = xt_flowoffload_net_hook; | ||||||
|  | +	ops->dev = dev; | ||||||
|  | + | ||||||
|  | +	hlist_add_head(&hook->list, &table->hooks); | ||||||
|  | +	mod_delayed_work(system_power_efficient_wq, &table->work, 0); | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static struct xt_flowoffload_hook * | ||||||
|  | +flow_offload_lookup_hook(struct xt_flowoffload_table *table, | ||||||
|  | +			 struct net_device *dev) | ||||||
|  | +{ | ||||||
|  | +	struct xt_flowoffload_hook *hook; | ||||||
|  | + | ||||||
|  | +	hlist_for_each_entry(hook, &table->hooks, list) { | ||||||
|  | +		if (hook->ops.dev == dev) | ||||||
|  | +			return hook; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return NULL; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void | ||||||
|  | +xt_flowoffload_check_device(struct xt_flowoffload_table *table, | ||||||
|  | +			    struct net_device *dev) | ||||||
|  | +{ | ||||||
|  | +	struct xt_flowoffload_hook *hook; | ||||||
|  | + | ||||||
|  | +	if (!dev) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	spin_lock_bh(&hooks_lock); | ||||||
|  | +	hook = flow_offload_lookup_hook(table, dev); | ||||||
|  | +	if (hook) | ||||||
|  | +		hook->used = true; | ||||||
|  | +	else | ||||||
|  | +		xt_flowoffload_create_hook(table, dev); | ||||||
|  | +	spin_unlock_bh(&hooks_lock); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void | ||||||
|  | +xt_flowoffload_register_hooks(struct xt_flowoffload_table *table) | ||||||
|  | +{ | ||||||
|  | +	struct xt_flowoffload_hook *hook; | ||||||
|  | + | ||||||
|  | +restart: | ||||||
|  | +	hlist_for_each_entry(hook, &table->hooks, list) { | ||||||
|  | +		if (hook->registered) | ||||||
|  | +			continue; | ||||||
|  | + | ||||||
|  | +		hook->registered = true; | ||||||
|  | +		hook->net = dev_net(hook->ops.dev); | ||||||
|  | +		spin_unlock_bh(&hooks_lock); | ||||||
|  | +		nf_register_net_hook(hook->net, &hook->ops); | ||||||
|  | +		if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD) | ||||||
|  | +			table->ft.type->setup(&table->ft, hook->ops.dev, | ||||||
|  | +					      FLOW_BLOCK_BIND); | ||||||
|  | +		spin_lock_bh(&hooks_lock); | ||||||
|  | +		goto restart; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static bool | ||||||
|  | +xt_flowoffload_cleanup_hooks(struct xt_flowoffload_table *table) | ||||||
|  | +{ | ||||||
|  | +	struct xt_flowoffload_hook *hook; | ||||||
|  | +	bool active = false; | ||||||
|  | + | ||||||
|  | +restart: | ||||||
|  | +	spin_lock_bh(&hooks_lock); | ||||||
|  | +	hlist_for_each_entry(hook, &table->hooks, list) { | ||||||
|  | +		if (hook->used || !hook->registered) { | ||||||
|  | +			active = true; | ||||||
|  | +			continue; | ||||||
|  | +		} | ||||||
|  | + | ||||||
|  | +		hlist_del(&hook->list); | ||||||
|  | +		spin_unlock_bh(&hooks_lock); | ||||||
|  | +		if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD) | ||||||
|  | +			table->ft.type->setup(&table->ft, hook->ops.dev, | ||||||
|  | +					      FLOW_BLOCK_UNBIND); | ||||||
|  | +		nf_unregister_net_hook(hook->net, &hook->ops); | ||||||
|  | +		kfree(hook); | ||||||
|  | +		goto restart; | ||||||
|  | +	} | ||||||
|  | +	spin_unlock_bh(&hooks_lock); | ||||||
|  | + | ||||||
|  | +	return active; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void | ||||||
|  | +xt_flowoffload_check_hook(struct flow_offload *flow, void *data) | ||||||
|  | +{ | ||||||
|  | +	struct xt_flowoffload_table *table = data; | ||||||
|  | +	struct flow_offload_tuple *tuple = &flow->tuplehash[0].tuple; | ||||||
|  | +	struct xt_flowoffload_hook *hook; | ||||||
|  | + | ||||||
|  | +	spin_lock_bh(&hooks_lock); | ||||||
|  | +	hlist_for_each_entry(hook, &table->hooks, list) { | ||||||
|  | +		int ifindex; | ||||||
|  | + | ||||||
|  | +		if (tuple->xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) | ||||||
|  | +			ifindex = tuple->out.ifidx; | ||||||
|  | +		else | ||||||
|  | +			ifindex = tuple->dst_cache->dev->ifindex; | ||||||
|  | + | ||||||
|  | +		if (hook->ops.dev->ifindex != tuple->iifidx && | ||||||
|  | +		    hook->ops.dev->ifindex != ifindex) | ||||||
|  | +			continue; | ||||||
|  | + | ||||||
|  | +		hook->used = true; | ||||||
|  | +	} | ||||||
|  | +	spin_unlock_bh(&hooks_lock); | ||||||
|  | + | ||||||
|  | +	cond_resched(); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void | ||||||
|  | +xt_flowoffload_hook_work(struct work_struct *work) | ||||||
|  | +{ | ||||||
|  | +	struct xt_flowoffload_table *table; | ||||||
|  | +	struct xt_flowoffload_hook *hook; | ||||||
|  | +	int err; | ||||||
|  | + | ||||||
|  | +	table = container_of(work, struct xt_flowoffload_table, work.work); | ||||||
|  | + | ||||||
|  | +	spin_lock_bh(&hooks_lock); | ||||||
|  | +	xt_flowoffload_register_hooks(table); | ||||||
|  | +	hlist_for_each_entry(hook, &table->hooks, list) | ||||||
|  | +		hook->used = false; | ||||||
|  | +	spin_unlock_bh(&hooks_lock); | ||||||
|  | + | ||||||
|  | +	err = nf_flow_table_iterate(&table->ft, xt_flowoffload_check_hook, | ||||||
|  | +				    table); | ||||||
|  | +	if (err && err != -EAGAIN) | ||||||
|  | +		goto out; | ||||||
|  | + | ||||||
|  | +	if (!xt_flowoffload_cleanup_hooks(table)) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +out: | ||||||
|  | +	queue_delayed_work(system_power_efficient_wq, &table->work, HZ); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static bool | ||||||
|  | +xt_flowoffload_skip(struct sk_buff *skb, int family) | ||||||
|  | +{ | ||||||
|  | +	if (skb_sec_path(skb)) | ||||||
|  | +		return true; | ||||||
|  | + | ||||||
|  | +	if (family == NFPROTO_IPV4) { | ||||||
|  | +		const struct ip_options *opt = &(IPCB(skb)->opt); | ||||||
|  | + | ||||||
|  | +		if (unlikely(opt->optlen)) | ||||||
|  | +			return true; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return false; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static bool flow_is_valid_ether_device(const struct net_device *dev) | ||||||
|  | +{ | ||||||
|  | +	if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER || | ||||||
|  | +	    dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr)) | ||||||
|  | +		return false; | ||||||
|  | + | ||||||
|  | +	return true; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void | ||||||
|  | +xt_flowoffload_route_check_path(struct nf_flow_route *route, | ||||||
|  | +				const struct nf_conn *ct, | ||||||
|  | +				enum ip_conntrack_dir dir, | ||||||
|  | +				struct net_device **out_dev) | ||||||
|  | +{ | ||||||
|  | +	const struct dst_entry *dst = route->tuple[dir].dst; | ||||||
|  | +	const void *daddr = &ct->tuplehash[!dir].tuple.src.u3; | ||||||
|  | +	struct net_device_path_stack stack; | ||||||
|  | +	enum net_device_path_type prev_type; | ||||||
|  | +	struct net_device *dev = dst->dev; | ||||||
|  | +	struct neighbour *n; | ||||||
|  | +	bool last = false; | ||||||
|  | +	u8 nud_state; | ||||||
|  | +	int i; | ||||||
|  | + | ||||||
|  | +	route->tuple[!dir].in.ifindex = dev->ifindex; | ||||||
|  | + | ||||||
|  | +	if (route->tuple[dir].xmit_type == FLOW_OFFLOAD_XMIT_XFRM) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	if ((dev->flags & IFF_LOOPBACK) || | ||||||
|  | +	    dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN || | ||||||
|  | +	    !is_valid_ether_addr(dev->dev_addr)) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	n = dst_neigh_lookup(dst, daddr); | ||||||
|  | +	if (!n) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	read_lock_bh(&n->lock); | ||||||
|  | +	nud_state = n->nud_state; | ||||||
|  | +	memcpy(route->tuple[dir].out.h_dest, n->ha, ETH_ALEN); | ||||||
|  | +	read_unlock_bh(&n->lock); | ||||||
|  | +	neigh_release(n); | ||||||
|  | + | ||||||
|  | +	if (!(nud_state & NUD_VALID)) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	if (dev_fill_forward_path(dev, route->tuple[dir].out.h_dest, &stack) || | ||||||
|  | +	    !stack.num_paths) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	prev_type = DEV_PATH_ETHERNET; | ||||||
|  | +	for (i = 0; i <= stack.num_paths; i++) { | ||||||
|  | +		const struct net_device_path *path = &stack.path[i]; | ||||||
|  | +		int n_vlans = route->tuple[!dir].in.num_vlans; | ||||||
|  | + | ||||||
|  | +		dev = (struct net_device *)path->dev; | ||||||
|  | +		if (flow_is_valid_ether_device(dev)) { | ||||||
|  | +			if (route->tuple[dir].xmit_type != FLOW_OFFLOAD_XMIT_DIRECT) | ||||||
|  | +				memcpy(route->tuple[dir].out.h_source, | ||||||
|  | +				       dev->dev_addr, ETH_ALEN); | ||||||
|  | +			route->tuple[dir].xmit_type = FLOW_OFFLOAD_XMIT_DIRECT; | ||||||
|  | +			route->tuple[dir].out.ifindex = dev->ifindex; | ||||||
|  | +		} | ||||||
|  | + | ||||||
|  | +		switch (path->type) { | ||||||
|  | +		case DEV_PATH_VLAN: | ||||||
|  | +			if (n_vlans >= NF_FLOW_TABLE_VLAN_MAX || | ||||||
|  | +			    i == stack.num_paths) { | ||||||
|  | +				last = true; | ||||||
|  | +				break; | ||||||
|  | +			} | ||||||
|  | + | ||||||
|  | +			route->tuple[!dir].in.num_vlans++; | ||||||
|  | +			route->tuple[!dir].in.vid[n_vlans] = path->vlan.id; | ||||||
|  | +			route->tuple[!dir].in.vproto[n_vlans] = path->vlan.proto; | ||||||
|  | +			break; | ||||||
|  | +		case DEV_PATH_BRIDGE: | ||||||
|  | +			switch (path->bridge.vlan_mode) { | ||||||
|  | +			case DEV_PATH_BR_VLAN_TAG: | ||||||
|  | +				if (n_vlans >= NF_FLOW_TABLE_VLAN_MAX || | ||||||
|  | +				    i == stack.num_paths) { | ||||||
|  | +					last = true; | ||||||
|  | +					break; | ||||||
|  | +				} | ||||||
|  | + | ||||||
|  | +				route->tuple[!dir].in.num_vlans++; | ||||||
|  | +				route->tuple[!dir].in.vid[n_vlans] = | ||||||
|  | +					path->bridge.vlan_id; | ||||||
|  | +				route->tuple[!dir].in.vproto[n_vlans] = | ||||||
|  | +					path->bridge.vlan_proto; | ||||||
|  | +				break; | ||||||
|  | +			case DEV_PATH_BR_VLAN_UNTAG_HW: | ||||||
|  | +				route->tuple[!dir].in.pvid.id = | ||||||
|  | +					route->tuple[!dir].in.vid[n_vlans - 1]; | ||||||
|  | +				route->tuple[!dir].in.pvid.proto = | ||||||
|  | +					route->tuple[!dir].in.vproto[n_vlans - 1]; | ||||||
|  | +				fallthrough; | ||||||
|  | +			case DEV_PATH_BR_VLAN_UNTAG: | ||||||
|  | +				route->tuple[!dir].in.num_vlans--; | ||||||
|  | +				break; | ||||||
|  | +			case DEV_PATH_BR_VLAN_KEEP: | ||||||
|  | +				break; | ||||||
|  | +			} | ||||||
|  | +			break; | ||||||
|  | +		default: | ||||||
|  | +			last = true; | ||||||
|  | +			break; | ||||||
|  | +		} | ||||||
|  | + | ||||||
|  | +		if (last) | ||||||
|  | +			break; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	*out_dev = dev; | ||||||
|  | +	route->tuple[!dir].in.ifindex = dev->ifindex; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int | ||||||
|  | +xt_flowoffload_route_dir(struct nf_flow_route *route, const struct nf_conn *ct, | ||||||
|  | +			 enum ip_conntrack_dir dir, | ||||||
|  | +			 const struct xt_action_param *par, int ifindex) | ||||||
|  | +{ | ||||||
|  | +	struct dst_entry *dst = NULL; | ||||||
|  | +	struct flowi fl; | ||||||
|  | + | ||||||
|  | +	memset(&fl, 0, sizeof(fl)); | ||||||
|  | +	switch (xt_family(par)) { | ||||||
|  | +	case NFPROTO_IPV4: | ||||||
|  | +		fl.u.ip4.daddr = ct->tuplehash[!dir].tuple.src.u3.ip; | ||||||
|  | +		fl.u.ip4.flowi4_oif = ifindex; | ||||||
|  | +		break; | ||||||
|  | +	case NFPROTO_IPV6: | ||||||
|  | +		fl.u.ip6.saddr = ct->tuplehash[!dir].tuple.dst.u3.in6; | ||||||
|  | +		fl.u.ip6.daddr = ct->tuplehash[!dir].tuple.src.u3.in6; | ||||||
|  | +		fl.u.ip6.flowi6_oif = ifindex; | ||||||
|  | +		break; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	nf_route(xt_net(par), &dst, &fl, false, xt_family(par)); | ||||||
|  | +	if (!dst) | ||||||
|  | +		return -ENOENT; | ||||||
|  | + | ||||||
|  | +	route->tuple[dir].dst = dst; | ||||||
|  | +	if (dst_xfrm(dst)) | ||||||
|  | +		route->tuple[dir].xmit_type = FLOW_OFFLOAD_XMIT_XFRM; | ||||||
|  | +	else | ||||||
|  | +		route->tuple[dir].xmit_type = FLOW_OFFLOAD_XMIT_NEIGH; | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int | ||||||
|  | +xt_flowoffload_route(struct sk_buff *skb, const struct nf_conn *ct, | ||||||
|  | +		     const struct xt_action_param *par, | ||||||
|  | +		     struct nf_flow_route *route, enum ip_conntrack_dir dir, | ||||||
|  | +		     struct net_device **dev) | ||||||
|  | +{ | ||||||
|  | +	int ret; | ||||||
|  | + | ||||||
|  | +	ret = xt_flowoffload_route_dir(route, ct, dir, par, | ||||||
|  | +				       dev[dir]->ifindex); | ||||||
|  | +	if (ret) | ||||||
|  | +		return ret; | ||||||
|  | + | ||||||
|  | +	ret = xt_flowoffload_route_dir(route, ct, !dir, par, | ||||||
|  | +				       dev[!dir]->ifindex); | ||||||
|  | +	if (ret) | ||||||
|  | +		return ret; | ||||||
|  | + | ||||||
|  | +	xt_flowoffload_route_check_path(route, ct, dir, &dev[!dir]); | ||||||
|  | +	xt_flowoffload_route_check_path(route, ct, !dir, &dev[dir]); | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static unsigned int | ||||||
|  | +flowoffload_tg(struct sk_buff *skb, const struct xt_action_param *par) | ||||||
|  | +{ | ||||||
|  | +	struct xt_flowoffload_table *table; | ||||||
|  | +	const struct xt_flowoffload_target_info *info = par->targinfo; | ||||||
|  | +	struct tcphdr _tcph, *tcph = NULL; | ||||||
|  | +	enum ip_conntrack_info ctinfo; | ||||||
|  | +	enum ip_conntrack_dir dir; | ||||||
|  | +	struct nf_flow_route route = {}; | ||||||
|  | +	struct flow_offload *flow = NULL; | ||||||
|  | +	struct net_device *devs[2] = {}; | ||||||
|  | +	struct nf_conn *ct; | ||||||
|  | +	struct net *net; | ||||||
|  | + | ||||||
|  | +	if (xt_flowoffload_skip(skb, xt_family(par))) | ||||||
|  | +		return XT_CONTINUE; | ||||||
|  | + | ||||||
|  | +	ct = nf_ct_get(skb, &ctinfo); | ||||||
|  | +	if (ct == NULL) | ||||||
|  | +		return XT_CONTINUE; | ||||||
|  | + | ||||||
|  | +	switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum) { | ||||||
|  | +	case IPPROTO_TCP: | ||||||
|  | +		if (ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED) | ||||||
|  | +			return XT_CONTINUE; | ||||||
|  | + | ||||||
|  | +		tcph = skb_header_pointer(skb, par->thoff, | ||||||
|  | +					  sizeof(_tcph), &_tcph); | ||||||
|  | +		if (unlikely(!tcph || tcph->fin || tcph->rst)) | ||||||
|  | +			return XT_CONTINUE; | ||||||
|  | +		break; | ||||||
|  | +	case IPPROTO_UDP: | ||||||
|  | +		break; | ||||||
|  | +	default: | ||||||
|  | +		return XT_CONTINUE; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	if (nf_ct_ext_exist(ct, NF_CT_EXT_HELPER) || | ||||||
|  | +	    ct->status & IPS_SEQ_ADJUST) | ||||||
|  | +		return XT_CONTINUE; | ||||||
|  | + | ||||||
|  | +	if (!nf_ct_is_confirmed(ct)) | ||||||
|  | +		return XT_CONTINUE; | ||||||
|  | + | ||||||
|  | +	devs[dir] = xt_out(par); | ||||||
|  | +	devs[!dir] = xt_in(par); | ||||||
|  | + | ||||||
|  | +	if (!devs[dir] || !devs[!dir]) | ||||||
|  | +		return XT_CONTINUE; | ||||||
|  | + | ||||||
|  | +	if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status)) | ||||||
|  | +		return XT_CONTINUE; | ||||||
|  | + | ||||||
|  | +	dir = CTINFO2DIR(ctinfo); | ||||||
|  | + | ||||||
|  | +	if (xt_flowoffload_route(skb, ct, par, &route, dir, devs) < 0) | ||||||
|  | +		goto err_flow_route; | ||||||
|  | + | ||||||
|  | +	flow = flow_offload_alloc(ct); | ||||||
|  | +	if (!flow) | ||||||
|  | +		goto err_flow_alloc; | ||||||
|  | + | ||||||
|  | +	if (flow_offload_route_init(flow, &route) < 0) | ||||||
|  | +		goto err_flow_add; | ||||||
|  | + | ||||||
|  | +	if (tcph) { | ||||||
|  | +		ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; | ||||||
|  | +		ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	table = &flowtable[!!(info->flags & XT_FLOWOFFLOAD_HW)]; | ||||||
|  | +	if (flow_offload_add(&table->ft, flow) < 0) | ||||||
|  | +		goto err_flow_add; | ||||||
|  | + | ||||||
|  | +	xt_flowoffload_check_device(table, devs[0]); | ||||||
|  | +	xt_flowoffload_check_device(table, devs[1]); | ||||||
|  | + | ||||||
|  | +	net = read_pnet(&table->ft.net); | ||||||
|  | +	if (!net) | ||||||
|  | +		write_pnet(&table->ft.net, xt_net(par)); | ||||||
|  | + | ||||||
|  | +	dst_release(route.tuple[dir].dst); | ||||||
|  | +	dst_release(route.tuple[!dir].dst); | ||||||
|  | + | ||||||
|  | +	return XT_CONTINUE; | ||||||
|  | + | ||||||
|  | +err_flow_add: | ||||||
|  | +	flow_offload_free(flow); | ||||||
|  | +err_flow_alloc: | ||||||
|  | +	dst_release(route.tuple[dir].dst); | ||||||
|  | +	dst_release(route.tuple[!dir].dst); | ||||||
|  | +err_flow_route: | ||||||
|  | +	clear_bit(IPS_OFFLOAD_BIT, &ct->status); | ||||||
|  | + | ||||||
|  | +	return XT_CONTINUE; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int flowoffload_chk(const struct xt_tgchk_param *par) | ||||||
|  | +{ | ||||||
|  | +	struct xt_flowoffload_target_info *info = par->targinfo; | ||||||
|  | + | ||||||
|  | +	if (info->flags & ~XT_FLOWOFFLOAD_MASK) | ||||||
|  | +		return -EINVAL; | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static struct xt_target offload_tg_reg __read_mostly = { | ||||||
|  | +	.family		= NFPROTO_UNSPEC, | ||||||
|  | +	.name		= "FLOWOFFLOAD", | ||||||
|  | +	.revision	= 0, | ||||||
|  | +	.targetsize	= sizeof(struct xt_flowoffload_target_info), | ||||||
|  | +	.usersize	= sizeof(struct xt_flowoffload_target_info), | ||||||
|  | +	.checkentry	= flowoffload_chk, | ||||||
|  | +	.target		= flowoffload_tg, | ||||||
|  | +	.me		= THIS_MODULE, | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +static int flow_offload_netdev_event(struct notifier_block *this, | ||||||
|  | +				     unsigned long event, void *ptr) | ||||||
|  | +{ | ||||||
|  | +	struct xt_flowoffload_hook *hook0, *hook1; | ||||||
|  | +	struct net_device *dev = netdev_notifier_info_to_dev(ptr); | ||||||
|  | + | ||||||
|  | +	if (event != NETDEV_UNREGISTER) | ||||||
|  | +		return NOTIFY_DONE; | ||||||
|  | + | ||||||
|  | +	spin_lock_bh(&hooks_lock); | ||||||
|  | +	hook0 = flow_offload_lookup_hook(&flowtable[0], dev); | ||||||
|  | +	if (hook0) | ||||||
|  | +		hlist_del(&hook0->list); | ||||||
|  | + | ||||||
|  | +	hook1 = flow_offload_lookup_hook(&flowtable[1], dev); | ||||||
|  | +	if (hook1) | ||||||
|  | +		hlist_del(&hook1->list); | ||||||
|  | +	spin_unlock_bh(&hooks_lock); | ||||||
|  | + | ||||||
|  | +	if (hook0) { | ||||||
|  | +		nf_unregister_net_hook(hook0->net, &hook0->ops); | ||||||
|  | +		kfree(hook0); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	if (hook1) { | ||||||
|  | +		nf_unregister_net_hook(hook1->net, &hook1->ops); | ||||||
|  | +		kfree(hook1); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	nf_flow_table_cleanup(dev); | ||||||
|  | + | ||||||
|  | +	return NOTIFY_DONE; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static struct notifier_block flow_offload_netdev_notifier = { | ||||||
|  | +	.notifier_call	= flow_offload_netdev_event, | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +static unsigned int | ||||||
|  | +nf_flow_offload_inet_hook(void *priv, struct sk_buff *skb, | ||||||
|  | +			  const struct nf_hook_state *state) | ||||||
|  | +{ | ||||||
|  | +	switch (skb->protocol) { | ||||||
|  | +	case htons(ETH_P_IP): | ||||||
|  | +		return nf_flow_offload_ip_hook(priv, skb, state); | ||||||
|  | +	case htons(ETH_P_IPV6): | ||||||
|  | +		return nf_flow_offload_ipv6_hook(priv, skb, state); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return NF_ACCEPT; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int nf_flow_rule_route_inet(struct net *net, | ||||||
|  | +				   const struct flow_offload *flow, | ||||||
|  | +				   enum flow_offload_tuple_dir dir, | ||||||
|  | +				   struct nf_flow_rule *flow_rule) | ||||||
|  | +{ | ||||||
|  | +	const struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple; | ||||||
|  | +	int err; | ||||||
|  | + | ||||||
|  | +	switch (flow_tuple->l3proto) { | ||||||
|  | +	case NFPROTO_IPV4: | ||||||
|  | +		err = nf_flow_rule_route_ipv4(net, flow, dir, flow_rule); | ||||||
|  | +		break; | ||||||
|  | +	case NFPROTO_IPV6: | ||||||
|  | +		err = nf_flow_rule_route_ipv6(net, flow, dir, flow_rule); | ||||||
|  | +		break; | ||||||
|  | +	default: | ||||||
|  | +		err = -1; | ||||||
|  | +		break; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return err; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static struct nf_flowtable_type flowtable_inet = { | ||||||
|  | +	.family		= NFPROTO_INET, | ||||||
|  | +	.init		= nf_flow_table_init, | ||||||
|  | +	.setup		= nf_flow_table_offload_setup, | ||||||
|  | +	.action		= nf_flow_rule_route_inet, | ||||||
|  | +	.free		= nf_flow_table_free, | ||||||
|  | +	.hook		= nf_flow_offload_inet_hook, | ||||||
|  | +	.owner		= THIS_MODULE, | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +static int init_flowtable(struct xt_flowoffload_table *tbl) | ||||||
|  | +{ | ||||||
|  | +	INIT_DELAYED_WORK(&tbl->work, xt_flowoffload_hook_work); | ||||||
|  | +	tbl->ft.type = &flowtable_inet; | ||||||
|  | + | ||||||
|  | +	return nf_flow_table_init(&tbl->ft); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int __init xt_flowoffload_tg_init(void) | ||||||
|  | +{ | ||||||
|  | +	int ret; | ||||||
|  | + | ||||||
|  | +	register_netdevice_notifier(&flow_offload_netdev_notifier); | ||||||
|  | + | ||||||
|  | +	ret = init_flowtable(&flowtable[0]); | ||||||
|  | +	if (ret) | ||||||
|  | +		return ret; | ||||||
|  | + | ||||||
|  | +	ret = init_flowtable(&flowtable[1]); | ||||||
|  | +	if (ret) | ||||||
|  | +		goto cleanup; | ||||||
|  | + | ||||||
|  | +	flowtable[1].ft.flags = NF_FLOWTABLE_HW_OFFLOAD; | ||||||
|  | + | ||||||
|  | +	ret = xt_register_target(&offload_tg_reg); | ||||||
|  | +	if (ret) | ||||||
|  | +		goto cleanup2; | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | + | ||||||
|  | +cleanup2: | ||||||
|  | +	nf_flow_table_free(&flowtable[1].ft); | ||||||
|  | +cleanup: | ||||||
|  | +	nf_flow_table_free(&flowtable[0].ft); | ||||||
|  | +	return ret; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void __exit xt_flowoffload_tg_exit(void) | ||||||
|  | +{ | ||||||
|  | +	xt_unregister_target(&offload_tg_reg); | ||||||
|  | +	unregister_netdevice_notifier(&flow_offload_netdev_notifier); | ||||||
|  | +	nf_flow_table_free(&flowtable[0].ft); | ||||||
|  | +	nf_flow_table_free(&flowtable[1].ft); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +MODULE_LICENSE("GPL"); | ||||||
|  | +module_init(xt_flowoffload_tg_init); | ||||||
|  | +module_exit(xt_flowoffload_tg_exit); | ||||||
|  | --- a/net/netfilter/nf_flow_table_core.c | ||||||
|  | +++ b/net/netfilter/nf_flow_table_core.c | ||||||
|  | @@ -7,7 +7,6 @@ | ||||||
|  |  #include <linux/netdevice.h> | ||||||
|  |  #include <net/ip.h> | ||||||
|  |  #include <net/ip6_route.h> | ||||||
|  | -#include <net/netfilter/nf_tables.h> | ||||||
|  |  #include <net/netfilter/nf_flow_table.h> | ||||||
|  |  #include <net/netfilter/nf_conntrack.h> | ||||||
|  |  #include <net/netfilter/nf_conntrack_core.h> | ||||||
|  | @@ -355,8 +354,7 @@ flow_offload_lookup(struct nf_flowtable | ||||||
|  |  } | ||||||
|  |  EXPORT_SYMBOL_GPL(flow_offload_lookup); | ||||||
|  |   | ||||||
|  | -static int | ||||||
|  | -nf_flow_table_iterate(struct nf_flowtable *flow_table, | ||||||
|  | +int nf_flow_table_iterate(struct nf_flowtable *flow_table, | ||||||
|  |  		      void (*iter)(struct flow_offload *flow, void *data), | ||||||
|  |  		      void *data) | ||||||
|  |  { | ||||||
|  | @@ -388,6 +386,7 @@ nf_flow_table_iterate(struct nf_flowtabl | ||||||
|  |   | ||||||
|  |  	return err; | ||||||
|  |  } | ||||||
|  | +EXPORT_SYMBOL_GPL(nf_flow_table_iterate); | ||||||
|  |   | ||||||
|  |  static void nf_flow_offload_gc_step(struct flow_offload *flow, void *data) | ||||||
|  |  { | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h | ||||||
|  | @@ -0,0 +1,17 @@ | ||||||
|  | +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | ||||||
|  | +#ifndef _XT_FLOWOFFLOAD_H | ||||||
|  | +#define _XT_FLOWOFFLOAD_H | ||||||
|  | + | ||||||
|  | +#include <linux/types.h> | ||||||
|  | + | ||||||
|  | +enum { | ||||||
|  | +	XT_FLOWOFFLOAD_HW	= 1 << 0, | ||||||
|  | + | ||||||
|  | +	XT_FLOWOFFLOAD_MASK	= XT_FLOWOFFLOAD_HW | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +struct xt_flowoffload_target_info { | ||||||
|  | +	__u32 flags; | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +#endif /* _XT_FLOWOFFLOAD_H */ | ||||||
|  | --- a/include/net/netfilter/nf_flow_table.h | ||||||
|  | +++ b/include/net/netfilter/nf_flow_table.h | ||||||
|  | @@ -265,6 +265,10 @@ void nf_flow_table_free(struct nf_flowta | ||||||
|  |   | ||||||
|  |  void flow_offload_teardown(struct flow_offload *flow); | ||||||
|  |   | ||||||
|  | +int nf_flow_table_iterate(struct nf_flowtable *flow_table, | ||||||
|  | +                      void (*iter)(struct flow_offload *flow, void *data), | ||||||
|  | +                      void *data); | ||||||
|  | + | ||||||
|  |  int nf_flow_snat_port(const struct flow_offload *flow, | ||||||
|  |  		      struct sk_buff *skb, unsigned int thoff, | ||||||
|  |  		      u8 protocol, enum flow_offload_tuple_dir dir); | ||||||
| @@ -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 | ||||||
|  | @@ -144,8 +144,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-5.10/660-fq_codel_defaults.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								target/linux/generic/hack-5.10/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 | ||||||
|  | @@ -461,7 +461,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); | ||||||
							
								
								
									
										100
									
								
								target/linux/generic/hack-5.10/661-use_fq_codel_by_default.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								target/linux/generic/hack-5.10/661-use_fq_codel_by_default.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | |||||||
|  | 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 | ||||||
|  | @@ -578,12 +578,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 | ||||||
|  | @@ -4,8 +4,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 | ||||||
|  | @@ -2282,7 +2282,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 | ||||||
|  | @@ -701,7 +701,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), | ||||||
|  | @@ -716,6 +716,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 <net/xfrm.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. */ | ||||||
|  | @@ -1018,12 +1018,12 @@ 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; | ||||||
|  |  	else if(dev->type == ARPHRD_CAN) | ||||||
|  | -		ops = &pfifo_fast_ops; | ||||||
|  | +		ops = &fq_codel_qdisc_ops; | ||||||
|  |   | ||||||
|  |  	qdisc = qdisc_create_dflt(dev_queue, ops, TC_H_ROOT, NULL); | ||||||
|  |  	if (!qdisc) | ||||||
							
								
								
									
										129
									
								
								target/linux/generic/hack-5.10/700-swconfig_switch_drivers.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								target/linux/generic/hack-5.10/700-swconfig_switch_drivers.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | |||||||
|  | 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 | ||||||
|  | @@ -61,6 +61,80 @@ config SFP | ||||||
|  |  	depends on HWMON || HWMON=n | ||||||
|  |  	select MDIO_I2C | ||||||
|  |   | ||||||
|  | +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 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 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 AMD_PHY | ||||||
|  | --- a/drivers/net/phy/Makefile | ||||||
|  | +++ b/drivers/net/phy/Makefile | ||||||
|  | @@ -24,6 +24,19 @@ 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_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_NETWORK_PHY_TIMESTAMPING) += mii_timestamper.o | ||||||
|  |   | ||||||
|  |  obj-$(CONFIG_SFP)		+= sfp.o | ||||||
|  | --- a/include/linux/platform_data/b53.h | ||||||
|  | +++ b/include/linux/platform_data/b53.h | ||||||
|  | @@ -29,6 +29,9 @@ struct b53_platform_data { | ||||||
|  |  	u32 chip_id; | ||||||
|  |  	u16 enabled_ports; | ||||||
|  |   | ||||||
|  | +	/* allow to specify an ethX alias */ | ||||||
|  | +	const char *alias; | ||||||
|  | + | ||||||
|  |  	/* only used by MMAP'd driver */ | ||||||
|  |  	unsigned big_endian:1; | ||||||
|  |  	void __iomem *regs; | ||||||
| @@ -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> | ||||||
|  | @@ -1408,6 +1409,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 | ||||||
|  |   **************************************************/ | ||||||
|  | @@ -1542,6 +1554,14 @@ int bgmac_enet_probe(struct bgmac *bgmac | ||||||
|  |  	/* Omit FCS from max MTU size */ | ||||||
|  |  	net_dev->max_mtu = BGMAC_RX_MAX_FRAME_SIZE - ETH_FCS_LEN; | ||||||
|  |   | ||||||
|  | +	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"); | ||||||
|  | @@ -1564,6 +1584,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 | ||||||
|  | @@ -428,6 +428,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 { | ||||||
|  | @@ -533,6 +534,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); | ||||||
							
								
								
									
										162
									
								
								target/linux/generic/hack-5.10/901-debloat_sock_diag.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								target/linux/generic/hack-5.10/901-debloat_sock_diag.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,162 @@ | |||||||
|  | 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 | ||||||
|  | @@ -98,6 +98,9 @@ source "net/mptcp/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 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 xdp.o flow_offload.o | ||||||
|  |   | ||||||
|  | +obj-$(CONFIG_SOCK_DIAG) += sock_diag.o | ||||||
|  |  obj-y += net-sysfs.o | ||||||
|  |  obj-$(CONFIG_PAGE_POOL) += page_pool.o | ||||||
|  |  obj-$(CONFIG_PROC_FS) += net-procfs.o | ||||||
|  | --- a/net/core/sock.c | ||||||
|  | +++ b/net/core/sock.c | ||||||
|  | @@ -114,6 +114,7 @@ | ||||||
|  |  #include <linux/memcontrol.h> | ||||||
|  |  #include <linux/prefetch.h> | ||||||
|  |  #include <linux/compat.h> | ||||||
|  | +#include <linux/cookie.h> | ||||||
|  |   | ||||||
|  |  #include <linux/uaccess.h> | ||||||
|  |   | ||||||
|  | @@ -141,6 +142,7 @@ | ||||||
|  |   | ||||||
|  |  static DEFINE_MUTEX(proto_list_mutex); | ||||||
|  |  static LIST_HEAD(proto_list); | ||||||
|  | +DEFINE_COOKIE(sock_cookie); | ||||||
|  |   | ||||||
|  |  static void sock_inuse_add(struct net *net, int val); | ||||||
|  |   | ||||||
|  | @@ -526,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 = gen_cookie_next(&sock_cookie); | ||||||
|  | +		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); | ||||||
|  | @@ -1808,9 +1822,11 @@ static void __sk_free(struct sock *sk) | ||||||
|  |  	if (likely(sk->sk_net_refcnt)) | ||||||
|  |  		sock_inuse_add(sock_net(sk), -1); | ||||||
|  |   | ||||||
|  | +#ifdef CONFIG_SOCK_DIAG | ||||||
|  |  	if (unlikely(sk->sk_net_refcnt && sock_diag_has_destroy_listeners(sk))) | ||||||
|  |  		sock_diag_broadcast_destroy(sk); | ||||||
|  |  	else | ||||||
|  | +#endif | ||||||
|  |  		sk_destruct(sk); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | --- a/net/core/sock_diag.c | ||||||
|  | +++ b/net/core/sock_diag.c | ||||||
|  | @@ -11,7 +11,6 @@ | ||||||
|  |  #include <linux/tcp.h> | ||||||
|  |  #include <linux/workqueue.h> | ||||||
|  |  #include <linux/nospec.h> | ||||||
|  | -#include <linux/cookie.h> | ||||||
|  |  #include <linux/inet_diag.h> | ||||||
|  |  #include <linux/sock_diag.h> | ||||||
|  |   | ||||||
|  | @@ -20,20 +19,6 @@ static int (*inet_rcv_compat)(struct sk_ | ||||||
|  |  static DEFINE_MUTEX(sock_diag_table_mutex); | ||||||
|  |  static struct workqueue_struct *broadcast_wq; | ||||||
|  |   | ||||||
|  | -DEFINE_COOKIE(sock_cookie); | ||||||
|  | - | ||||||
|  | -u64 __sock_gen_cookie(struct sock *sk) | ||||||
|  | -{ | ||||||
|  | -	while (1) { | ||||||
|  | -		u64 res = atomic64_read(&sk->sk_cookie); | ||||||
|  | - | ||||||
|  | -		if (res) | ||||||
|  | -			return res; | ||||||
|  | -		res = gen_cookie_next(&sock_cookie); | ||||||
|  | -		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 | ||||||
|  | @@ -414,6 +414,7 @@ config INET_TUNNEL | ||||||
|  |   | ||||||
|  |  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 | ||||||
|  | @@ -5,6 +5,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 | ||||||
|  | @@ -19,6 +19,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 | ||||||
|  | @@ -28,6 +28,7 @@ config UNIX_SCM | ||||||
|  |  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. | ||||||
							
								
								
									
										408
									
								
								target/linux/generic/hack-5.10/902-debloat_proc.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										408
									
								
								target/linux/generic/hack-5.10/902-debloat_proc.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,408 @@ | |||||||
|  | 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 | ||||||
|  | @@ -2996,6 +2996,8 @@ static const struct seq_operations locks | ||||||
|  |   | ||||||
|  |  static int __init proc_locks_init(void) | ||||||
|  |  { | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return 0; | ||||||
|  |  	proc_create_seq_private("locks", 0, NULL, &locks_seq_operations, | ||||||
|  |  			sizeof(struct locks_iterator), NULL); | ||||||
|  |  	return 0; | ||||||
|  | --- a/fs/proc/Kconfig | ||||||
|  | +++ b/fs/proc/Kconfig | ||||||
|  | @@ -100,6 +100,11 @@ 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" | ||||||
|  | + | ||||||
|  |  config PROC_PID_ARCH_STATUS | ||||||
|  |  	def_bool n | ||||||
|  |  	depends on PROC_FS | ||||||
|  | --- a/fs/proc/consoles.c | ||||||
|  | +++ b/fs/proc/consoles.c | ||||||
|  | @@ -92,6 +92,9 @@ static const struct seq_operations conso | ||||||
|  |   | ||||||
|  |  static int __init proc_consoles_init(void) | ||||||
|  |  { | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  |  	proc_create_seq("consoles", 0, NULL, &consoles_op); | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  | --- a/fs/proc/proc_tty.c | ||||||
|  | +++ b/fs/proc/proc_tty.c | ||||||
|  | @@ -133,7 +133,10 @@ static const struct seq_operations tty_d | ||||||
|  |  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_show) | ||||||
|  |  		return; | ||||||
|  | @@ -150,6 +153,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; | ||||||
|  | @@ -164,6 +170,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 | ||||||
|  | @@ -124,6 +124,21 @@ struct linux_tls_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]) | ||||||
|  |   | ||||||
|  | @@ -154,8 +169,9 @@ struct linux_tls_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 | ||||||
|  | @@ -1348,6 +1348,9 @@ void __init msg_init(void) | ||||||
|  |  { | ||||||
|  |  	msg_init_ns(&init_ipc_ns); | ||||||
|  |   | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  |  	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 | ||||||
|  | @@ -266,6 +266,8 @@ void sem_exit_ns(struct ipc_namespace *n | ||||||
|  |  void __init sem_init(void) | ||||||
|  |  { | ||||||
|  |  	sem_init_ns(&init_ipc_ns); | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return; | ||||||
|  |  	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 | ||||||
|  | @@ -144,6 +144,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 | ||||||
|  | @@ -140,6 +140,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 | ||||||
|  | @@ -29,6 +29,8 @@ static int execdomains_proc_show(struct | ||||||
|  |   | ||||||
|  |  static int __init proc_execdomains_init(void) | ||||||
|  |  { | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return 0; | ||||||
|  |  	proc_create_single("execdomains", 0, NULL, execdomains_proc_show); | ||||||
|  |  	return 0; | ||||||
|  |  } | ||||||
|  | --- a/kernel/irq/proc.c | ||||||
|  | +++ b/kernel/irq/proc.c | ||||||
|  | @@ -341,6 +341,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; | ||||||
|  |   | ||||||
|  | @@ -394,6 +397,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 | ||||||
|  | @@ -432,6 +438,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 | ||||||
|  | @@ -370,6 +370,8 @@ static int __init init_timer_list_procfs | ||||||
|  |  { | ||||||
|  |  	struct proc_dir_entry *pe; | ||||||
|  |   | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return 0; | ||||||
|  |  	pe = proc_create_seq_private("timer_list", 0400, NULL, &timer_list_sops, | ||||||
|  |  			sizeof(struct timer_list_iter), NULL); | ||||||
|  |  	if (!pe) | ||||||
|  | --- a/mm/vmalloc.c | ||||||
|  | +++ b/mm/vmalloc.c | ||||||
|  | @@ -3572,6 +3572,8 @@ static const struct seq_operations vmall | ||||||
|  |   | ||||||
|  |  static int __init proc_vmalloc_init(void) | ||||||
|  |  { | ||||||
|  | +	if (IS_ENABLED(CONFIG_PROC_STRIPPED)) | ||||||
|  | +		return 0; | ||||||
|  |  	if (IS_ENABLED(CONFIG_NUMA)) | ||||||
|  |  		proc_create_seq_private("vmallocinfo", 0400, NULL, | ||||||
|  |  				&vmalloc_op, | ||||||
|  | --- a/mm/vmstat.c | ||||||
|  | +++ b/mm/vmstat.c | ||||||
|  | @@ -2044,10 +2044,12 @@ void __init init_mm_internals(void) | ||||||
|  |  	start_shepherd_timer(); | ||||||
|  |  #endif | ||||||
|  |  #ifdef CONFIG_PROC_FS | ||||||
|  | -	proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op); | ||||||
|  | -	proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op); | ||||||
|  | +	if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) { | ||||||
|  | +		proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op); | ||||||
|  | +		proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op); | ||||||
|  | +		proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op); | ||||||
|  | +	} | ||||||
|  |  	proc_create_seq("vmstat", 0444, NULL, &vmstat_op); | ||||||
|  | -	proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op); | ||||||
|  |  #endif | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | --- a/net/8021q/vlanproc.c | ||||||
|  | +++ b/net/8021q/vlanproc.c | ||||||
|  | @@ -93,6 +93,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); | ||||||
|  |   | ||||||
|  | @@ -112,6 +115,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 | ||||||
|  | @@ -290,10 +290,12 @@ static int __net_init dev_proc_net_init( | ||||||
|  |  	if (!proc_create_net("dev", 0444, net->proc_net, &dev_seq_ops, | ||||||
|  |  			sizeof(struct seq_net_private))) | ||||||
|  |  		goto out; | ||||||
|  | -	if (!proc_create_seq("softnet_stat", 0444, net->proc_net, | ||||||
|  | +	if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && | ||||||
|  | +			!proc_create_seq("softnet_stat", 0444, net->proc_net, | ||||||
|  |  			 &softnet_seq_ops)) | ||||||
|  |  		goto out_dev; | ||||||
|  | -	if (!proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops, | ||||||
|  | +	if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && | ||||||
|  | +			!proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops, | ||||||
|  |  			sizeof(struct seq_net_private))) | ||||||
|  |  		goto out_softnet; | ||||||
|  |   | ||||||
|  | @@ -303,9 +305,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; | ||||||
|  | @@ -315,8 +319,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 | ||||||
|  | @@ -3680,6 +3680,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 | ||||||
|  | @@ -2986,11 +2986,13 @@ static const struct seq_operations fib_r | ||||||
|  |   | ||||||
|  |  int __net_init fib_proc_init(struct net *net) | ||||||
|  |  { | ||||||
|  | -	if (!proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops, | ||||||
|  | +	if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && | ||||||
|  | +			!proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops, | ||||||
|  |  			sizeof(struct fib_trie_iter))) | ||||||
|  |  		goto out1; | ||||||
|  |   | ||||||
|  | -	if (!proc_create_net_single("fib_triestat", 0444, net->proc_net, | ||||||
|  | +	if (!IS_ENABLED(CONFIG_PROC_STRIPPED) && | ||||||
|  | +			!proc_create_net_single("fib_triestat", 0444, net->proc_net, | ||||||
|  |  			fib_triestat_seq_show, NULL)) | ||||||
|  |  		goto out2; | ||||||
|  |   | ||||||
|  | @@ -3001,17 +3003,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 | ||||||
|  | @@ -528,5 +528,8 @@ 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 | ||||||
|  | @@ -409,6 +409,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); | ||||||
|  |  } | ||||||
|  |   | ||||||
							
								
								
									
										82
									
								
								target/linux/generic/hack-5.10/904-debloat_dma_buf.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								target/linux/generic/hack-5.10/904-debloat_dma_buf.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | |||||||
|  | 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 | ||||||
|  | @@ -184,7 +184,7 @@ config SOC_BUS | ||||||
|  |  source "drivers/base/regmap/Kconfig" | ||||||
|  |   | ||||||
|  |  config DMA_SHARED_BUFFER | ||||||
|  | -	bool | ||||||
|  | +	tristate | ||||||
|  |  	default n | ||||||
|  |  	select IRQ_WORK | ||||||
|  |  	help | ||||||
|  | --- a/drivers/dma-buf/Makefile | ||||||
|  | +++ b/drivers/dma-buf/Makefile | ||||||
|  | @@ -1,15 +1,19 @@ | ||||||
|  |  # SPDX-License-Identifier: GPL-2.0-only | ||||||
|  | -obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \ | ||||||
|  | +obj-$(CONFIG_DMA_SHARED_BUFFER) := dma-shared-buffer.o | ||||||
|  | + | ||||||
|  | +dma-buf-objs-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \ | ||||||
|  |  	 dma-resv.o seqno-fence.o | ||||||
|  | -obj-$(CONFIG_DMABUF_HEAPS)	+= dma-heap.o | ||||||
|  | -obj-$(CONFIG_DMABUF_HEAPS)	+= heaps/ | ||||||
|  | -obj-$(CONFIG_SYNC_FILE)		+= sync_file.o | ||||||
|  | -obj-$(CONFIG_SW_SYNC)		+= sw_sync.o sync_debug.o | ||||||
|  | -obj-$(CONFIG_UDMABUF)		+= udmabuf.o | ||||||
|  | +dma-buf-objs-$(CONFIG_DMABUF_HEAPS)	+= dma-heap.o | ||||||
|  | +dma-buf-objs-$(CONFIG_DMABUF_HEAPS)	+= heaps/ | ||||||
|  | +dma-buf-objs-$(CONFIG_SYNC_FILE)		+= sync_file.o | ||||||
|  | +dma-buf-objs-$(CONFIG_SW_SYNC)		+= sw_sync.o sync_debug.o | ||||||
|  | +dma-buf-objs-$(CONFIG_UDMABUF)		+= udmabuf.o | ||||||
|  |   | ||||||
|  |  dmabuf_selftests-y := \ | ||||||
|  |  	selftest.o \ | ||||||
|  |  	st-dma-fence.o \ | ||||||
|  |  	st-dma-fence-chain.o | ||||||
|  |   | ||||||
|  | -obj-$(CONFIG_DMABUF_SELFTESTS)	+= dmabuf_selftests.o | ||||||
|  | +dma-buf-objs-$(CONFIG_DMABUF_SELFTESTS)	+= dmabuf_selftests.o | ||||||
|  | + | ||||||
|  | +dma-shared-buffer-objs :=  $(dma-buf-objs-y) | ||||||
|  | --- a/drivers/dma-buf/dma-buf.c | ||||||
|  | +++ b/drivers/dma-buf/dma-buf.c | ||||||
|  | @@ -1418,4 +1418,5 @@ static void __exit dma_buf_deinit(void) | ||||||
|  |  	dma_buf_uninit_debugfs(); | ||||||
|  |  	kern_unmount(dma_buf_mnt); | ||||||
|  |  } | ||||||
|  | -__exitcall(dma_buf_deinit); | ||||||
|  | +module_exit(dma_buf_deinit); | ||||||
|  | +MODULE_LICENSE("GPL"); | ||||||
|  | --- a/kernel/sched/core.c | ||||||
|  | +++ b/kernel/sched/core.c | ||||||
|  | @@ -3054,6 +3054,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. | ||||||
|  | --- a/fs/d_path.c | ||||||
|  | +++ b/fs/d_path.c | ||||||
|  | @@ -311,6 +311,7 @@ char *dynamic_dname(struct dentry *dentr | ||||||
|  |  	buffer += buflen - sz; | ||||||
|  |  	return memcpy(buffer, temp, sz); | ||||||
|  |  } | ||||||
|  | +EXPORT_SYMBOL_GPL(dynamic_dname); | ||||||
|  |   | ||||||
|  |  char *simple_dname(struct dentry *dentry, char *buffer, int buflen) | ||||||
|  |  { | ||||||
							
								
								
									
										32
									
								
								target/linux/generic/hack-5.10/910-kobject_uevent.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								target/linux/generic/hack-5.10/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 | ||||||
|  | @@ -179,6 +179,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			64	/* 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[]; | ||||||
|  | @@ -244,4 +246,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 | ||||||
|  | @@ -690,6 +690,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_broadcast(struct sock *usk, struct sk_buff *skb, | ||||||
|  |  				struct netlink_ext_ack *extack) | ||||||
|  |  { | ||||||
| @@ -0,0 +1,29 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Thu, 22 Oct 2020 22:00:03 +0200 | ||||||
|  | Subject: [PATCH] compiler.h: only include asm/rwonce.h for kernel code | ||||||
|  |  | ||||||
|  | This header file is not in uapi, which makes any user space code that includes | ||||||
|  | linux/compiler.h to fail with the error 'asm/rwonce.h: No such file or directory' | ||||||
|  |  | ||||||
|  | Fixes: e506ea451254 ("compiler.h: Split {READ,WRITE}_ONCE definitions out into rwonce.h") | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/include/linux/compiler.h | ||||||
|  | +++ b/include/linux/compiler.h | ||||||
|  | @@ -211,6 +211,8 @@ void ftrace_likely_update(struct ftrace_ | ||||||
|  |  	__v;								\ | ||||||
|  |  }) | ||||||
|  |   | ||||||
|  | +#include <asm/rwonce.h> | ||||||
|  | + | ||||||
|  |  #endif /* __KERNEL__ */ | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  | @@ -243,6 +245,4 @@ static inline void *offset_to_ptr(const | ||||||
|  |   */ | ||||||
|  |  #define prevent_tail_call_optimization()	mb() | ||||||
|  |   | ||||||
|  | -#include <asm/rwonce.h> | ||||||
|  | - | ||||||
|  |  #endif /* __LINUX_COMPILER_H */ | ||||||
| @@ -0,0 +1,57 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Date: Wed, 18 Apr 2018 10:50:05 +0200 | ||||||
|  | Subject: [PATCH] MIPS: only process negative stack offsets on stack traces | ||||||
|  |  | ||||||
|  | Fixes endless back traces in cases where the compiler emits a stack | ||||||
|  | pointer increase in a branch delay slot (probably for some form of | ||||||
|  | function return). | ||||||
|  |  | ||||||
|  | [    3.475442] BUG: MAX_STACK_TRACE_ENTRIES too low! | ||||||
|  | [    3.480070] turning off the locking correctness validator. | ||||||
|  | [    3.485521] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.14.34 #0 | ||||||
|  | [    3.491475] Stack : 00000000 00000000 00000000 00000000 80e0fce2 00000034 00000000 00000000 | ||||||
|  | [    3.499764]         87c3838c 80696377 8061047c 00000000 00000001 00000001 87c2d850 6534689f | ||||||
|  | [    3.508059]         00000000 00000000 80e10000 00000000 00000000 000000cf 0000000f 00000000 | ||||||
|  | [    3.516353]         00000000 806a0000 00076891 00000000 00000000 00000000 ffffffff 00000000 | ||||||
|  | [    3.524648]         806c0000 00000004 80e10000 806a0000 00000003 80690000 00000000 80700000 | ||||||
|  | [    3.532942]         ... | ||||||
|  | [    3.535362] Call Trace: | ||||||
|  | [    3.537818] [<80010a48>] show_stack+0x58/0x100 | ||||||
|  | [    3.542207] [<804c2f78>] dump_stack+0xe8/0x170 | ||||||
|  | [    3.546613] [<80079f90>] save_trace+0xf0/0x110 | ||||||
|  | [    3.551010] [<8007b1ec>] mark_lock+0x33c/0x78c | ||||||
|  | [    3.555413] [<8007bf48>] __lock_acquire+0x2ac/0x1a08 | ||||||
|  | [    3.560337] [<8007de60>] lock_acquire+0x64/0x8c | ||||||
|  | [    3.564846] [<804e1570>] _raw_spin_lock_irqsave+0x54/0x78 | ||||||
|  | [    3.570186] [<801b618c>] kernfs_notify+0x94/0xac | ||||||
|  | [    3.574770] [<801b7b10>] sysfs_notify+0x74/0xa0 | ||||||
|  | [    3.579257] [<801b618c>] kernfs_notify+0x94/0xac | ||||||
|  | [    3.583839] [<801b7b10>] sysfs_notify+0x74/0xa0 | ||||||
|  | [    3.588329] [<801b618c>] kernfs_notify+0x94/0xac | ||||||
|  | [    3.592911] [<801b7b10>] sysfs_notify+0x74/0xa0 | ||||||
|  | [    3.597401] [<801b618c>] kernfs_notify+0x94/0xac | ||||||
|  | [    3.601983] [<801b7b10>] sysfs_notify+0x74/0xa0 | ||||||
|  | [    3.606473] [<801b618c>] kernfs_notify+0x94/0xac | ||||||
|  | [    3.611055] [<801b7b10>] sysfs_notify+0x74/0xa0 | ||||||
|  | [    3.615545] [<801b618c>] kernfs_notify+0x94/0xac | ||||||
|  | [    3.620125] [<801b7b10>] sysfs_notify+0x74/0xa0 | ||||||
|  | [    3.624619] [<801b618c>] kernfs_notify+0x94/0xac | ||||||
|  | [    3.629197] [<801b7b10>] sysfs_notify+0x74/0xa0 | ||||||
|  | [    3.633691] [<801b618c>] kernfs_notify+0x94/0xac | ||||||
|  | [    3.638269] [<801b7b10>] sysfs_notify+0x74/0xa0 | ||||||
|  | [    3.642763] [<801b618c>] kernfs_notify+0x94/0xac | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/arch/mips/kernel/process.c | ||||||
|  | +++ b/arch/mips/kernel/process.c | ||||||
|  | @@ -380,6 +380,8 @@ static inline int is_sp_move_ins(union m | ||||||
|  |   | ||||||
|  |  	if (ip->i_format.opcode == addiu_op || | ||||||
|  |  	    ip->i_format.opcode == daddiu_op) { | ||||||
|  | +		if (ip->i_format.simmediate > 0) | ||||||
|  | +			return 0; | ||||||
|  |  		*frame_size = -ip->i_format.simmediate; | ||||||
|  |  		return 1; | ||||||
|  |  	} | ||||||
| @@ -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 | ||||||
|  | @@ -643,7 +643,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; | ||||||
|  | @@ -1013,7 +1013,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 | ||||||
|  | @@ -327,6 +327,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 | ||||||
|  | @@ -218,6 +218,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 | ||||||
|  | @@ -50,6 +50,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 | ||||||
|  | @@ -6951,7 +6951,7 @@ static void __ref alloc_node_mem_map(str | ||||||
|  |  	if (pgdat == NODE_DATA(0)) { | ||||||
|  |  		mem_map = NODE_DATA(0)->node_mem_map; | ||||||
|  |  		if (page_to_pfn(mem_map) != pgdat->node_start_pfn) | ||||||
|  | -			mem_map -= offset; | ||||||
|  | +			mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET); | ||||||
|  |  	} | ||||||
|  |  #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 | ||||||
|  | @@ -682,6 +682,7 @@ static const struct of_device_id spidev_ | ||||||
|  |  	{ .compatible = "lwn,bk4" }, | ||||||
|  |  	{ .compatible = "dh,dhcom-board" }, | ||||||
|  |  	{ .compatible = "menlo,m53cpld" }, | ||||||
|  | +	{ .compatible = "siliconlabs,si3210" }, | ||||||
|  |  	{}, | ||||||
|  |  }; | ||||||
|  |  MODULE_DEVICE_TABLE(of, spidev_dt_ids); | ||||||
| @@ -0,0 +1,78 @@ | |||||||
|  | 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 | ||||||
|  | @@ -609,7 +609,8 @@ static int jffs2_rmdir (struct inode *di | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, umode_t mode, dev_t rdev) | ||||||
|  | +static int __jffs2_mknod (struct inode *dir_i, struct dentry *dentry, | ||||||
|  | +			  umode_t mode, dev_t rdev, bool whiteout) | ||||||
|  |  { | ||||||
|  |  	struct jffs2_inode_info *f, *dir_f; | ||||||
|  |  	struct jffs2_sb_info *c; | ||||||
|  | @@ -748,7 +749,11 @@ static int jffs2_mknod (struct inode *di | ||||||
|  |  	mutex_unlock(&dir_f->sem); | ||||||
|  |  	jffs2_complete_reservation(c); | ||||||
|  |   | ||||||
|  | -	d_instantiate_new(dentry, inode); | ||||||
|  | +	if (!whiteout) | ||||||
|  | +		d_instantiate_new(dentry, inode); | ||||||
|  | +	else | ||||||
|  | +		unlock_new_inode(inode); | ||||||
|  | + | ||||||
|  |  	return 0; | ||||||
|  |   | ||||||
|  |   fail: | ||||||
|  | @@ -756,6 +761,17 @@ static int jffs2_mknod (struct inode *di | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, umode_t mode, dev_t rdev) | ||||||
|  | +{ | ||||||
|  | +	return __jffs2_mknod(dir_i, dentry, mode, rdev, false); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int jffs2_whiteout (struct inode *old_dir, struct dentry *old_dentry) | ||||||
|  | +{ | ||||||
|  | +	return __jffs2_mknod(old_dir, old_dentry, S_IFCHR | WHITEOUT_MODE, | ||||||
|  | +			     WHITEOUT_DEV, true); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  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 +782,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 +848,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 | ||||||
|  | @@ -779,18 +779,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; | ||||||
|  | @@ -825,7 +838,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)); | ||||||
|  | @@ -851,6 +864,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), | ||||||
|  | @@ -882,7 +901,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,20 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: jffs2: add splice ops | ||||||
|  |  | ||||||
|  | Add splice_read using generic_file_splice_read. | ||||||
|  | Add splice_write using iter_file_splice_write | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/fs/jffs2/file.c | ||||||
|  | +++ b/fs/jffs2/file.c | ||||||
|  | @@ -53,6 +53,8 @@ const struct file_operations jffs2_file_ | ||||||
|  |  	.open =		generic_file_open, | ||||||
|  |   	.read_iter =	generic_file_read_iter, | ||||||
|  |   	.write_iter =	generic_file_write_iter, | ||||||
|  | +	.splice_read =	generic_file_splice_read, | ||||||
|  | +	.splice_write =	iter_file_splice_write, | ||||||
|  |  	.unlocked_ioctl=jffs2_ioctl, | ||||||
|  |  	.mmap =		generic_file_readonly_mmap, | ||||||
|  |  	.fsync =	jffs2_fsync, | ||||||
| @@ -0,0 +1,45 @@ | |||||||
|  | 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 | ||||||
|  | @@ -195,6 +195,9 @@ static void __br_handle_local_finish(str | ||||||
|  |  /* note: already called with rcu_read_lock */ | ||||||
|  |  static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb) | ||||||
|  |  { | ||||||
|  | +	struct net_bridge_port *p = br_port_get_rcu(skb->dev); | ||||||
|  | + | ||||||
|  | +	if (p->state != BR_STATE_DISABLED) | ||||||
|  |  	__br_handle_local_finish(skb); | ||||||
|  |   | ||||||
|  |  	/* return 1 to signal the okfn() was called so it's ok to use the skb */ | ||||||
|  | @@ -348,6 +351,17 @@ static rx_handler_result_t br_handle_fra | ||||||
|  |   | ||||||
|  |  forward: | ||||||
|  |  	switch (p->state) { | ||||||
|  | +	case BR_STATE_DISABLED: | ||||||
|  | +		if (ether_addr_equal(p->br->dev->dev_addr, dest)) | ||||||
|  | +			skb->pkt_type = PACKET_HOST; | ||||||
|  | + | ||||||
|  | +		if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, | ||||||
|  | +			dev_net(skb->dev), NULL, skb, skb->dev, NULL, | ||||||
|  | +			br_handle_local_finish) == 1) { | ||||||
|  | +			return RX_HANDLER_PASS; | ||||||
|  | +		} | ||||||
|  | +		break; | ||||||
|  | + | ||||||
|  |  	case BR_STATE_FORWARDING: | ||||||
|  |  	case BR_STATE_LEARNING: | ||||||
|  |  		if (ether_addr_equal(p->br->dev->dev_addr, dest)) | ||||||
| @@ -0,0 +1,94 @@ | |||||||
|  | From: Daniel González Cabanelas <dgcbueu@gmail.com> | ||||||
|  | Subject: [PATCH 1/2] rtc: rs5c372: support alarms up to 1 week | ||||||
|  |  | ||||||
|  | The Ricoh R2221x, R2223x, RS5C372, RV5C387A chips can handle 1 week | ||||||
|  | alarms. | ||||||
|  |  | ||||||
|  | Read the "wday" alarm register and convert it to a date to support up 1 | ||||||
|  | week in our driver. | ||||||
|  |  | ||||||
|  | Signed-off-by: Daniel González Cabanelas <dgcbueu@gmail.com> | ||||||
|  | --- | ||||||
|  |  drivers/rtc/rtc-rs5c372.c | 48 ++++++++++++++++++++++++++++++++++----- | ||||||
|  |  1 file changed, 42 insertions(+), 6 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/rtc/rtc-rs5c372.c | ||||||
|  | +++ b/drivers/rtc/rtc-rs5c372.c | ||||||
|  | @@ -393,7 +393,9 @@ static int rs5c_read_alarm(struct device | ||||||
|  |  { | ||||||
|  |  	struct i2c_client	*client = to_i2c_client(dev); | ||||||
|  |  	struct rs5c372		*rs5c = i2c_get_clientdata(client); | ||||||
|  | -	int			status; | ||||||
|  | +	int			status, wday_offs; | ||||||
|  | +	struct rtc_time 	rtc; | ||||||
|  | +	unsigned long 		alarm_secs; | ||||||
|  |   | ||||||
|  |  	status = rs5c_get_regs(rs5c); | ||||||
|  |  	if (status < 0) | ||||||
|  | @@ -403,6 +405,30 @@ static int rs5c_read_alarm(struct device | ||||||
|  |  	t->time.tm_sec = 0; | ||||||
|  |  	t->time.tm_min = bcd2bin(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f); | ||||||
|  |  	t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]); | ||||||
|  | +	t->time.tm_wday = ffs(rs5c->regs[RS5C_REG_ALARM_A_WDAY] & 0x7f) - 1; | ||||||
|  | + | ||||||
|  | +	/* determine the day, month and year based on alarm wday, taking as a | ||||||
|  | +	 * reference the current time from the rtc | ||||||
|  | +	 */ | ||||||
|  | +	status = rs5c372_rtc_read_time(dev, &rtc); | ||||||
|  | +	if (status < 0) | ||||||
|  | +		return status; | ||||||
|  | + | ||||||
|  | +	wday_offs = t->time.tm_wday - rtc.tm_wday; | ||||||
|  | +	alarm_secs = mktime64(rtc.tm_year + 1900, | ||||||
|  | +			      rtc.tm_mon + 1, | ||||||
|  | +			      rtc.tm_mday + wday_offs, | ||||||
|  | +			      t->time.tm_hour, | ||||||
|  | +			      t->time.tm_min, | ||||||
|  | +			      t->time.tm_sec); | ||||||
|  | + | ||||||
|  | +	if (wday_offs < 0 || (wday_offs == 0 && | ||||||
|  | +			      (t->time.tm_hour < rtc.tm_hour || | ||||||
|  | +			       (t->time.tm_hour == rtc.tm_hour && | ||||||
|  | +				t->time.tm_min <= rtc.tm_min)))) | ||||||
|  | +		alarm_secs += 7 * 86400; | ||||||
|  | + | ||||||
|  | +	rtc_time64_to_tm(alarm_secs, &t->time); | ||||||
|  |   | ||||||
|  |  	/* ... and status */ | ||||||
|  |  	t->enabled = !!(rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE); | ||||||
|  | @@ -417,12 +443,20 @@ static int rs5c_set_alarm(struct device | ||||||
|  |  	struct rs5c372		*rs5c = i2c_get_clientdata(client); | ||||||
|  |  	int			status, addr, i; | ||||||
|  |  	unsigned char		buf[3]; | ||||||
|  | +	struct rtc_time 	rtc_tm; | ||||||
|  | +	unsigned long 		rtc_secs, alarm_secs; | ||||||
|  |   | ||||||
|  | -	/* only handle up to 24 hours in the future, like RTC_ALM_SET */ | ||||||
|  | -	if (t->time.tm_mday != -1 | ||||||
|  | -			|| t->time.tm_mon != -1 | ||||||
|  | -			|| t->time.tm_year != -1) | ||||||
|  | +	/* chip only can handle alarms up to one week in the future*/ | ||||||
|  | +	status = rs5c372_rtc_read_time(dev, &rtc_tm); | ||||||
|  | +	if (status) | ||||||
|  | +		return status; | ||||||
|  | +	rtc_secs = rtc_tm_to_time64(&rtc_tm); | ||||||
|  | +	alarm_secs = rtc_tm_to_time64(&t->time); | ||||||
|  | +	if (alarm_secs >= rtc_secs + 7 * 86400) { | ||||||
|  | +		dev_err(dev, "%s: alarm maximum is one week in the future (%d)\n", | ||||||
|  | +			__func__, status); | ||||||
|  |  		return -EINVAL; | ||||||
|  | +	} | ||||||
|  |   | ||||||
|  |  	/* REVISIT: round up tm_sec */ | ||||||
|  |   | ||||||
|  | @@ -443,7 +477,9 @@ static int rs5c_set_alarm(struct device | ||||||
|  |  	/* set alarm */ | ||||||
|  |  	buf[0] = bin2bcd(t->time.tm_min); | ||||||
|  |  	buf[1] = rs5c_hr2reg(rs5c, t->time.tm_hour); | ||||||
|  | -	buf[2] = 0x7f;	/* any/all days */ | ||||||
|  | +	/* each bit is the day of the week, 0x7f means all days */ | ||||||
|  | +	buf[2] = (t->time.tm_wday >= 0 && t->time.tm_wday < 7) ? | ||||||
|  | +		  BIT(t->time.tm_wday) : 0x7f; | ||||||
|  |   | ||||||
|  |  	for (i = 0; i < sizeof(buf); i++) { | ||||||
|  |  		addr = RS5C_ADDR(RS5C_REG_ALARM_A_MIN + i); | ||||||
| @@ -0,0 +1,70 @@ | |||||||
|  | From: Daniel González Cabanelas <dgcbueu@gmail.com> | ||||||
|  | Subject: [PATCH 2/2] rtc: rs5c372: let the alarm to be used as wakeup source | ||||||
|  |  | ||||||
|  | Currently there is no use for the interrupts on the rs5c372 RTC and the | ||||||
|  | wakealarm isn't enabled. There are some devices like NASes which use this | ||||||
|  | RTC to wake up from the power off state when the INTR pin is activated by | ||||||
|  | the alarm clock. | ||||||
|  |  | ||||||
|  | Enable the alarm and let to be used as a wakeup source. | ||||||
|  |  | ||||||
|  | Tested on a Buffalo LS421DE NAS. | ||||||
|  |  | ||||||
|  | Signed-off-by: Daniel González Cabanelas <dgcbueu@gmail.com> | ||||||
|  | --- | ||||||
|  |  drivers/rtc/rtc-rs5c372.c | 16 ++++++++++++++++ | ||||||
|  |  1 file changed, 16 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/rtc/rtc-rs5c372.c | ||||||
|  | +++ b/drivers/rtc/rtc-rs5c372.c | ||||||
|  | @@ -654,6 +654,7 @@ static int rs5c372_probe(struct i2c_clie | ||||||
|  |  	int err = 0; | ||||||
|  |  	int smbus_mode = 0; | ||||||
|  |  	struct rs5c372 *rs5c372; | ||||||
|  | +	bool rs5c372_can_wakeup_device = false; | ||||||
|  |   | ||||||
|  |  	dev_dbg(&client->dev, "%s\n", __func__); | ||||||
|  |   | ||||||
|  | @@ -689,6 +690,12 @@ static int rs5c372_probe(struct i2c_clie | ||||||
|  |  	else | ||||||
|  |  		rs5c372->type = id->driver_data; | ||||||
|  |   | ||||||
|  | +#ifdef CONFIG_OF | ||||||
|  | +	if(of_property_read_bool(client->dev.of_node, | ||||||
|  | +					      "wakeup-source")) | ||||||
|  | +		rs5c372_can_wakeup_device = true; | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  |  	/* we read registers 0x0f then 0x00-0x0f; skip the first one */ | ||||||
|  |  	rs5c372->regs = &rs5c372->buf[1]; | ||||||
|  |  	rs5c372->smbus = smbus_mode; | ||||||
|  | @@ -722,6 +729,8 @@ static int rs5c372_probe(struct i2c_clie | ||||||
|  |  		goto exit; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	rs5c372->has_irq = 1; | ||||||
|  | + | ||||||
|  |  	/* if the oscillator lost power and no other software (like | ||||||
|  |  	 * the bootloader) set it up, do it here. | ||||||
|  |  	 * | ||||||
|  | @@ -748,6 +757,10 @@ static int rs5c372_probe(struct i2c_clie | ||||||
|  |  			); | ||||||
|  |   | ||||||
|  |  	/* REVISIT use client->irq to register alarm irq ... */ | ||||||
|  | +	if (rs5c372_can_wakeup_device) { | ||||||
|  | +		device_init_wakeup(&client->dev, true); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	rs5c372->rtc = devm_rtc_device_register(&client->dev, | ||||||
|  |  					rs5c372_driver.driver.name, | ||||||
|  |  					&rs5c372_rtc_ops, THIS_MODULE); | ||||||
|  | @@ -761,6 +774,9 @@ static int rs5c372_probe(struct i2c_clie | ||||||
|  |  	if (err) | ||||||
|  |  		goto exit; | ||||||
|  |   | ||||||
|  | +	/* the rs5c372 alarm only supports a minute accuracy */ | ||||||
|  | +	rs5c372->rtc->uie_unsupported = 1; | ||||||
|  | + | ||||||
|  |  	return 0; | ||||||
|  |   | ||||||
|  |  exit: | ||||||
| @@ -0,0 +1,31 @@ | |||||||
|  | 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 | ||||||
|  | @@ -733,11 +733,11 @@ KBUILD_CFLAGS	+= $(call cc-disable-warni | ||||||
|  |  KBUILD_CFLAGS	+= $(call cc-disable-warning, address-of-packed-member) | ||||||
|  |   | ||||||
|  |  ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE | ||||||
|  | -KBUILD_CFLAGS += -O2 | ||||||
|  | +KBUILD_CFLAGS += -O2 $(EXTRA_OPTIMIZATION) | ||||||
|  |  else ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3 | ||||||
|  | -KBUILD_CFLAGS += -O3 | ||||||
|  | +KBUILD_CFLAGS += -O3 $(EXTRA_OPTIMIZATION) | ||||||
|  |  else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE | ||||||
|  | -KBUILD_CFLAGS += -Os | ||||||
|  | +KBUILD_CFLAGS += -Os -fno-reorder-blocks -fno-tree-ch $(EXTRA_OPTIMIZATION) | ||||||
|  |  endif | ||||||
|  |   | ||||||
|  |  # Tell gcc to never replace conditional load with a non-conditional one | ||||||
| @@ -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 | ||||||
|  | @@ -1384,6 +1384,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 | ||||||
|  | @@ -77,6 +77,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++; | ||||||
|  | @@ -109,6 +114,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 | ||||||
|  | @@ -58,6 +58,7 @@ static struct addr_range percpu_range = | ||||||
|  |  static struct sym_entry **table; | ||||||
|  |  static unsigned int table_size, table_cnt; | ||||||
|  |  static int all_symbols; | ||||||
|  | +static int uncompressed; | ||||||
|  |  static int absolute_percpu; | ||||||
|  |  static int base_relative; | ||||||
|  |   | ||||||
|  | @@ -480,6 +481,9 @@ static void write_src(void) | ||||||
|  |   | ||||||
|  |  	free(markers); | ||||||
|  |   | ||||||
|  | +	if (uncompressed) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  |  	output_label("kallsyms_token_table"); | ||||||
|  |  	off = 0; | ||||||
|  |  	for (i = 0; i < 256; i++) { | ||||||
|  | @@ -531,6 +535,9 @@ static unsigned char *find_token(unsigne | ||||||
|  |  { | ||||||
|  |  	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]; | ||||||
|  | @@ -603,6 +610,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--) { | ||||||
|  | @@ -767,6 +777,8 @@ int main(int argc, char **argv) | ||||||
|  |  				absolute_percpu = 1; | ||||||
|  |  			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 | ||||||
|  | @@ -186,6 +186,10 @@ kallsyms() | ||||||
|  |  		kallsymopt="${kallsymopt} --base-relative" | ||||||
|  |  	fi | ||||||
|  |   | ||||||
|  | +	if [ -n "${CONFIG_KALLSYMS_UNCOMPRESSED}" ]; then | ||||||
|  | +		kallsymopt="${kallsymopt} --uncompressed" | ||||||
|  | +	fi | ||||||
|  | + | ||||||
|  |  	info KSYMS ${2} | ||||||
|  |  	${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${2} | ||||||
|  |  } | ||||||
| @@ -0,0 +1,41 @@ | |||||||
|  | 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 | ||||||
|  | @@ -957,8 +957,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') | ||||||
|  | @@ -975,8 +977,14 @@ char *symbol_string(char *buf, char *end | ||||||
|  |   | ||||||
|  |  	return string_nocheck(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 const struct printf_spec default_str_spec = { | ||||||
| @@ -0,0 +1,30 @@ | |||||||
|  | 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> | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  usr/Makefile | 8 +++++--- | ||||||
|  |  1 file changed, 5 insertions(+), 3 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/usr/Makefile | ||||||
|  | +++ b/usr/Makefile | ||||||
|  | @@ -61,6 +61,8 @@ hostprogs := gen_init_cpio | ||||||
|  |  # The dependency list is generated by gen_initramfs.sh -l | ||||||
|  |  -include $(obj)/.initramfs_data.cpio.d | ||||||
|  |   | ||||||
|  | +deps_initramfs := $(foreach v,$(deps_initramfs),$(if $(findstring :,$(v)),,$(v))) | ||||||
|  | + | ||||||
|  |  # do not try to update files included in initramfs | ||||||
|  |  $(deps_initramfs): ; | ||||||
|  |   | ||||||
| @@ -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 | ||||||
|  | @@ -20,7 +20,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,31 @@ | |||||||
|  | From c2deb5ef01a0ef09088832744cbace9e239a6ee0 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= <hacks@slashdirt.org> | ||||||
|  | Date: Sat, 28 Mar 2020 12:11:50 +0100 | ||||||
|  | Subject: [PATCH] generic: platform/mikrotik build bits (5.4) | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Type: text/plain; charset=UTF-8 | ||||||
|  | Content-Transfer-Encoding: 8bit | ||||||
|  |  | ||||||
|  | This patch adds platform/mikrotik kernel build bits | ||||||
|  |  | ||||||
|  | Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org> | ||||||
|  | --- | ||||||
|  |  drivers/platform/Kconfig  | 2 ++ | ||||||
|  |  drivers/platform/Makefile | 1 + | ||||||
|  |  2 files changed, 3 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/platform/Kconfig | ||||||
|  | +++ b/drivers/platform/Kconfig | ||||||
|  | @@ -13,3 +13,5 @@ source "drivers/platform/chrome/Kconfig" | ||||||
|  |  source "drivers/platform/mellanox/Kconfig" | ||||||
|  |   | ||||||
|  |  source "drivers/platform/olpc/Kconfig" | ||||||
|  | + | ||||||
|  | +source "drivers/platform/mikrotik/Kconfig" | ||||||
|  | --- a/drivers/platform/Makefile | ||||||
|  | +++ b/drivers/platform/Makefile | ||||||
|  | @@ -9,3 +9,4 @@ obj-$(CONFIG_MIPS)		+= mips/ | ||||||
|  |  obj-$(CONFIG_OLPC_EC)		+= olpc/ | ||||||
|  |  obj-$(CONFIG_GOLDFISH)		+= goldfish/ | ||||||
|  |  obj-$(CONFIG_CHROME_PLATFORMS)	+= chrome/ | ||||||
|  | +obj-$(CONFIG_MIKROTIK)		+= mikrotik/ | ||||||
| @@ -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 | ||||||
|  | @@ -1077,9 +1077,6 @@ config FW_ARC | ||||||
|  |  config ARCH_MAY_HAVE_PC_FDC | ||||||
|  |  	bool | ||||||
|  |   | ||||||
|  | -config BOOT_RAW | ||||||
|  | -	bool | ||||||
|  | - | ||||||
|  |  config CEVT_BCM1480 | ||||||
|  |  	bool | ||||||
|  |   | ||||||
|  | @@ -3169,6 +3166,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 | ||||||
|  | @@ -95,7 +95,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 | ||||||
							
								
								
									
										371
									
								
								target/linux/generic/pending-5.10/305-mips_module_reloc.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										371
									
								
								target/linux/generic/pending-5.10/305-mips_module_reloc.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,371 @@ | |||||||
|  | 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 | ||||||
|  | @@ -98,8 +98,18 @@ 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 | ||||||
|  | +  ifdef CONFIG_DYNAMIC_FTRACE | ||||||
|  | +    KBUILD_AFLAGS_MODULE	+= -mlong-calls | ||||||
|  | +    KBUILD_CFLAGS_MODULE	+= -mlong-calls | ||||||
|  | +  else | ||||||
|  | +    KBUILD_AFLAGS_MODULE	+= -mno-long-calls | ||||||
|  | +    KBUILD_CFLAGS_MODULE	+= -mno-long-calls | ||||||
|  | +  endif | ||||||
|  | +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 | ||||||
|  | @@ -31,14 +31,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) | ||||||
|  | @@ -54,9 +261,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); | ||||||
|  | @@ -64,13 +302,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; | ||||||
|  |  } | ||||||
|  | @@ -446,9 +688,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,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 | ||||||
|  | @@ -54,7 +54,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-5.10/308-mips32r2_tune.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								target/linux/generic/pending-5.10/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 | ||||||
|  | @@ -155,7 +155,7 @@ cflags-$(CONFIG_CPU_VR41XX)	+= -march=r4 | ||||||
|  |  cflags-$(CONFIG_CPU_R4X00)	+= -march=r4600 -Wa,--trap | ||||||
|  |  cflags-$(CONFIG_CPU_TX49XX)	+= -march=r4600 -Wa,--trap | ||||||
|  |  cflags-$(CONFIG_CPU_MIPS32_R1)	+= -march=mips32 -Wa,--trap | ||||||
|  | -cflags-$(CONFIG_CPU_MIPS32_R2)	+= -march=mips32r2 -Wa,--trap | ||||||
|  | +cflags-$(CONFIG_CPU_MIPS32_R2)	+= -march=mips32r2 -mtune=34kc -Wa,--trap | ||||||
|  |  cflags-$(CONFIG_CPU_MIPS32_R5)	+= -march=mips32r5 -Wa,--trap -modd-spreg | ||||||
|  |  cflags-$(CONFIG_CPU_MIPS32_R6)	+= -march=mips32r6 -Wa,--trap -modd-spreg | ||||||
|  |  cflags-$(CONFIG_CPU_MIPS64_R1)	+= -march=mips64 -Wa,--trap | ||||||
| @@ -0,0 +1,140 @@ | |||||||
|  | From 87ec87c2ad615c1a177cd08ef5fa29fc739f6e50 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Hauke Mehrtens <hauke@hauke-m.de> | ||||||
|  | Date: Sun, 23 Dec 2018 18:06:53 +0100 | ||||||
|  | Subject: [PATCH] MIPS: Add CPU option reporting to /proc/cpuinfo | ||||||
|  |  | ||||||
|  | Many MIPS CPUs have optional CPU features which are not activates for | ||||||
|  | all CPU cores. Print the CPU options which are implemented in the core | ||||||
|  | in /proc/cpuinfo. This makes it possible to see what features are | ||||||
|  | supported and which are not supported. This should cover all standard | ||||||
|  | MIPS extensions, before it only printed information about the main MIPS | ||||||
|  | ASEs. | ||||||
|  |  | ||||||
|  | Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> | ||||||
|  | --- | ||||||
|  |  arch/mips/kernel/proc.c | 116 ++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  1 file changed, 116 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/arch/mips/kernel/proc.c | ||||||
|  | +++ b/arch/mips/kernel/proc.c | ||||||
|  | @@ -138,6 +138,120 @@ static int show_cpuinfo(struct seq_file | ||||||
|  |  		seq_printf(m, "micromips kernel\t: %s\n", | ||||||
|  |  		      (read_c0_config3() & MIPS_CONF3_ISA_OE) ?  "yes" : "no"); | ||||||
|  |  	} | ||||||
|  | + | ||||||
|  | +	seq_printf(m, "Options implemented\t:"); | ||||||
|  | +	if (cpu_has_tlb) | ||||||
|  | +		seq_printf(m, "%s", " tlb"); | ||||||
|  | +	if (cpu_has_ftlb) | ||||||
|  | +		seq_printf(m, "%s", " ftlb"); | ||||||
|  | +	if (cpu_has_tlbinv) | ||||||
|  | +		seq_printf(m, "%s", " tlbinv"); | ||||||
|  | +	if (cpu_has_segments) | ||||||
|  | +		seq_printf(m, "%s", " segments"); | ||||||
|  | +	if (cpu_has_rixiex) | ||||||
|  | +		seq_printf(m, "%s", " rixiex"); | ||||||
|  | +	if (cpu_has_ldpte) | ||||||
|  | +		seq_printf(m, "%s", " ldpte"); | ||||||
|  | +	if (cpu_has_maar) | ||||||
|  | +		seq_printf(m, "%s", " maar"); | ||||||
|  | +	if (cpu_has_rw_llb) | ||||||
|  | +		seq_printf(m, "%s", " rw_llb"); | ||||||
|  | +	if (cpu_has_4kex) | ||||||
|  | +		seq_printf(m, "%s", " 4kex"); | ||||||
|  | +	if (cpu_has_3k_cache) | ||||||
|  | +		seq_printf(m, "%s", " 3k_cache"); | ||||||
|  | +	if (cpu_has_4k_cache) | ||||||
|  | +		seq_printf(m, "%s", " 4k_cache"); | ||||||
|  | +	if (cpu_has_6k_cache) | ||||||
|  | +		seq_printf(m, "%s", " 6k_cache"); | ||||||
|  | +	if (cpu_has_8k_cache) | ||||||
|  | +		seq_printf(m, "%s", " 8k_cache"); | ||||||
|  | +	if (cpu_has_tx39_cache) | ||||||
|  | +		seq_printf(m, "%s", " tx39_cache"); | ||||||
|  | +	if (cpu_has_octeon_cache) | ||||||
|  | +		seq_printf(m, "%s", " octeon_cache"); | ||||||
|  | +	if (cpu_has_fpu) | ||||||
|  | +		seq_printf(m, "%s", " fpu"); | ||||||
|  | +	if (cpu_has_32fpr) | ||||||
|  | +		seq_printf(m, "%s", " 32fpr"); | ||||||
|  | +	if (cpu_has_cache_cdex_p) | ||||||
|  | +		seq_printf(m, "%s", " cache_cdex_p"); | ||||||
|  | +	if (cpu_has_cache_cdex_s) | ||||||
|  | +		seq_printf(m, "%s", " cache_cdex_s"); | ||||||
|  | +	if (cpu_has_prefetch) | ||||||
|  | +		seq_printf(m, "%s", " prefetch"); | ||||||
|  | +	if (cpu_has_mcheck) | ||||||
|  | +		seq_printf(m, "%s", " mcheck"); | ||||||
|  | +	if (cpu_has_ejtag) | ||||||
|  | +		seq_printf(m, "%s", " ejtag"); | ||||||
|  | +	if (cpu_has_llsc) | ||||||
|  | +		seq_printf(m, "%s", " llsc"); | ||||||
|  | +	if (cpu_has_guestctl0ext) | ||||||
|  | +		seq_printf(m, "%s", " guestctl0ext"); | ||||||
|  | +	if (cpu_has_guestctl1) | ||||||
|  | +		seq_printf(m, "%s", " guestctl1"); | ||||||
|  | +	if (cpu_has_guestctl2) | ||||||
|  | +		seq_printf(m, "%s", " guestctl2"); | ||||||
|  | +	if (cpu_has_guestid) | ||||||
|  | +		seq_printf(m, "%s", " guestid"); | ||||||
|  | +	if (cpu_has_drg) | ||||||
|  | +		seq_printf(m, "%s", " drg"); | ||||||
|  | +	if (cpu_has_rixi) | ||||||
|  | +		seq_printf(m, "%s", " rixi"); | ||||||
|  | +	if (cpu_has_lpa) | ||||||
|  | +		seq_printf(m, "%s", " lpa"); | ||||||
|  | +	if (cpu_has_mvh) | ||||||
|  | +		seq_printf(m, "%s", " mvh"); | ||||||
|  | +	if (cpu_has_vtag_icache) | ||||||
|  | +		seq_printf(m, "%s", " vtag_icache"); | ||||||
|  | +	if (cpu_has_dc_aliases) | ||||||
|  | +		seq_printf(m, "%s", " dc_aliases"); | ||||||
|  | +	if (cpu_has_ic_fills_f_dc) | ||||||
|  | +		seq_printf(m, "%s", " ic_fills_f_dc"); | ||||||
|  | +	if (cpu_has_pindexed_dcache) | ||||||
|  | +		seq_printf(m, "%s", " pindexed_dcache"); | ||||||
|  | +	if (cpu_has_userlocal) | ||||||
|  | +		seq_printf(m, "%s", " userlocal"); | ||||||
|  | +	if (cpu_has_nofpuex) | ||||||
|  | +		seq_printf(m, "%s", " nofpuex"); | ||||||
|  | +	if (cpu_has_vint) | ||||||
|  | +		seq_printf(m, "%s", " vint"); | ||||||
|  | +	if (cpu_has_veic) | ||||||
|  | +		seq_printf(m, "%s", " veic"); | ||||||
|  | +	if (cpu_has_inclusive_pcaches) | ||||||
|  | +		seq_printf(m, "%s", " inclusive_pcaches"); | ||||||
|  | +	if (cpu_has_perf_cntr_intr_bit) | ||||||
|  | +		seq_printf(m, "%s", " perf_cntr_intr_bit"); | ||||||
|  | +	if (cpu_has_ufr) | ||||||
|  | +		seq_printf(m, "%s", " ufr"); | ||||||
|  | +	if (cpu_has_fre) | ||||||
|  | +		seq_printf(m, "%s", " fre"); | ||||||
|  | +	if (cpu_has_cdmm) | ||||||
|  | +		seq_printf(m, "%s", " cdmm"); | ||||||
|  | +	if (cpu_has_small_pages) | ||||||
|  | +		seq_printf(m, "%s", " small_pages"); | ||||||
|  | +	if (cpu_has_nan_legacy) | ||||||
|  | +		seq_printf(m, "%s", " nan_legacy"); | ||||||
|  | +	if (cpu_has_nan_2008) | ||||||
|  | +		seq_printf(m, "%s", " nan_2008"); | ||||||
|  | +	if (cpu_has_ebase_wg) | ||||||
|  | +		seq_printf(m, "%s", " ebase_wg"); | ||||||
|  | +	if (cpu_has_badinstr) | ||||||
|  | +		seq_printf(m, "%s", " badinstr"); | ||||||
|  | +	if (cpu_has_badinstrp) | ||||||
|  | +		seq_printf(m, "%s", " badinstrp"); | ||||||
|  | +	if (cpu_has_contextconfig) | ||||||
|  | +		seq_printf(m, "%s", " contextconfig"); | ||||||
|  | +	if (cpu_has_perf) | ||||||
|  | +		seq_printf(m, "%s", " perf"); | ||||||
|  | +	if (cpu_has_shared_ftlb_ram) | ||||||
|  | +		seq_printf(m, "%s", " shared_ftlb_ram"); | ||||||
|  | +	if (cpu_has_shared_ftlb_entries) | ||||||
|  | +		seq_printf(m, "%s", " shared_ftlb_entries"); | ||||||
|  | +	if (cpu_has_mipsmt_pertccounters) | ||||||
|  | +		seq_printf(m, "%s", " mipsmt_pertccounters"); | ||||||
|  | +	seq_printf(m, "\n"); | ||||||
|  | + | ||||||
|  |  	seq_printf(m, "shadow register sets\t: %d\n", | ||||||
|  |  		      cpu_data[n].srsets); | ||||||
|  |  	seq_printf(m, "kscratch registers\t: %d\n", | ||||||
| @@ -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 | ||||||
|  | @@ -105,6 +105,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,36 @@ | |||||||
|  | From 7d1531c81c0fb4c93bea8dc316043ad0e4d0c270 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Chuanhong Guo <gch981213@gmail.com> | ||||||
|  | Date: Sun, 25 Oct 2020 23:19:40 +0800 | ||||||
|  | Subject: [PATCH] MIPS: zboot: put appended dtb into a section | ||||||
|  |  | ||||||
|  | This will make a separated section for dtb appear in ELF, and we can | ||||||
|  | then use objcopy to patch a dtb into vmlinuz when RAW_APPENDED_DTB | ||||||
|  | is set in kernel config. | ||||||
|  |  | ||||||
|  | command to patch a dtb: | ||||||
|  | objcopy --set-section-flags=.appended_dtb=alloc,contents \ | ||||||
|  |         --update-section=.appended_dtb=<target>.dtb vmlinuz vmlinuz-dtb | ||||||
|  |  | ||||||
|  | Signed-off-by: Chuanhong Guo <gch981213@gmail.com> | ||||||
|  | --- | ||||||
|  |  arch/mips/boot/compressed/ld.script | 9 ++++++--- | ||||||
|  |  1 file changed, 6 insertions(+), 3 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/arch/mips/boot/compressed/ld.script | ||||||
|  | +++ b/arch/mips/boot/compressed/ld.script | ||||||
|  | @@ -31,9 +31,12 @@ SECTIONS | ||||||
|  |  		CONSTRUCTORS | ||||||
|  |  		. = ALIGN(16); | ||||||
|  |  	} | ||||||
|  | -	__appended_dtb = .; | ||||||
|  | -	/* leave space for appended DTB */ | ||||||
|  | -	. += 0x100000; | ||||||
|  | + | ||||||
|  | +	.appended_dtb : { | ||||||
|  | +		__appended_dtb = .; | ||||||
|  | +		/* leave space for appended DTB */ | ||||||
|  | +		. += 0x100000; | ||||||
|  | +	} | ||||||
|  |   | ||||||
|  |  	_edata = .; | ||||||
|  |  	/* End of data section */ | ||||||
| @@ -0,0 +1,281 @@ | |||||||
|  | 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 | ||||||
|  | @@ -9,14 +9,11 @@ | ||||||
|  |  #include <linux/delay.h> | ||||||
|  |  #include <linux/libfdt.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 <linux/uaccess.h> | ||||||
|  | +#include "machine_kexec.h" | ||||||
|  |   | ||||||
|  |  static unsigned long reboot_code_buffer; | ||||||
|  |   | ||||||
|  | @@ -30,6 +27,101 @@ void (*_crash_smp_send_stop)(void) = NUL | ||||||
|  |  void (*_machine_kexec_shutdown)(void) = NULL; | ||||||
|  |  void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL; | ||||||
|  |   | ||||||
|  | +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 */ | ||||||
|  | +	if (copy_from_user(kexec_argv_buf, buf, size)) | ||||||
|  | +		pr_warn("kexec command line copy to kernel space failed\n"); | ||||||
|  | + | ||||||
|  | +	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; | ||||||
|  | @@ -99,6 +191,18 @@ machine_kexec_prepare(struct kimage *kim | ||||||
|  |  #endif | ||||||
|  |   | ||||||
|  |  	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); | ||||||
|  | @@ -161,7 +265,7 @@ machine_crash_shutdown(struct pt_regs *r | ||||||
|  |  void kexec_nonboot_cpu_jump(void) | ||||||
|  |  { | ||||||
|  |  	local_flush_icache_range((unsigned long)relocated_kexec_smp_wait, | ||||||
|  | -				 reboot_code_buffer + relocate_new_kernel_size); | ||||||
|  | +				 reboot_code_buffer + KEXEC_RELOCATE_NEW_KERNEL_SIZE); | ||||||
|  |   | ||||||
|  |  	relocated_kexec_smp_wait(NULL); | ||||||
|  |  } | ||||||
|  | @@ -199,7 +303,7 @@ void kexec_reboot(void) | ||||||
|  |  	 * machine_kexec() CPU. | ||||||
|  |  	 */ | ||||||
|  |  	local_flush_icache_range(reboot_code_buffer, | ||||||
|  | -				 reboot_code_buffer + relocate_new_kernel_size); | ||||||
|  | +				 reboot_code_buffer + KEXEC_RELOCATE_NEW_KERNEL_SIZE); | ||||||
|  |   | ||||||
|  |  	do_kexec = (void *)reboot_code_buffer; | ||||||
|  |  	do_kexec(); | ||||||
|  | @@ -212,10 +316,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 = | ||||||
|  | @@ -223,9 +329,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 | ||||||
|  | @@ -256,7 +372,7 @@ machine_kexec(struct kimage *image) | ||||||
|  |  #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 | ||||||
|  | @@ -10,8 +10,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 | ||||||
|  | @@ -96,7 +97,7 @@ done: | ||||||
|  |  #endif | ||||||
|  |  	/* jump to kexec_start_address */ | ||||||
|  |  	j		s1 | ||||||
|  | -	END(relocate_new_kernel) | ||||||
|  | +	END(kexec_relocate_new_kernel) | ||||||
|  |   | ||||||
|  |  #ifdef CONFIG_SMP | ||||||
|  |  /* | ||||||
|  | @@ -182,9 +183,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 | ||||||
|  |   | ||||||
|  | -relocate_new_kernel_size: | ||||||
|  | -	EXPORT(relocate_new_kernel_size) | ||||||
|  | -	PTR		relocate_new_kernel_end - relocate_new_kernel | ||||||
|  | -	.size		relocate_new_kernel_size, PTRSIZE | ||||||
|  | +kexec_argv: | ||||||
|  | +	EXPORT(kexec_argv) | ||||||
|  | +	.skip		KEXEC_ARGV_SIZE | ||||||
|  | +	.size		kexec_argv, KEXEC_ARGV_SIZE | ||||||
|  | + | ||||||
|  | +kexec_relocate_new_kernel_end: | ||||||
|  | +	EXPORT(kexec_relocate_new_kernel_end) | ||||||
| @@ -0,0 +1,84 @@ | |||||||
|  | From bb0c3b0175240bf152fd7c644821a0cf9f77c37c Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Evgeniy Didin <Evgeniy.Didin@synopsys.com> | ||||||
|  | Date: Fri, 15 Mar 2019 18:53:38 +0300 | ||||||
|  | Subject: [PATCH] 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: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> | ||||||
|  | Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com> | ||||||
|  | Signed-off-by: Evgeniy Didin <Evgeniy.Didin@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 | ||||||
|  | @@ -88,6 +88,16 @@ | ||||||
|  |  	DSP_EARLY_INIT | ||||||
|  |  .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 | ||||||
|  | @@ -495,6 +495,8 @@ static inline bool uboot_arg_invalid(uns | ||||||
|  |  /* We always pass 0 as magic from U-boot */ | ||||||
|  |  #define UBOOT_MAGIC_VALUE	0 | ||||||
|  |   | ||||||
|  | +extern struct boot_param_header __image_dtb; | ||||||
|  | + | ||||||
|  |  void __init handle_uboot_args(void) | ||||||
|  |  { | ||||||
|  |  	bool use_embedded_dtb = true; | ||||||
|  | @@ -533,7 +535,7 @@ void __init handle_uboot_args(void) | ||||||
|  |  ignore_uboot_args: | ||||||
|  |   | ||||||
|  |  	if (use_embedded_dtb) { | ||||||
|  | -		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 | ||||||
|  | @@ -27,6 +27,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 | ||||||
|  | @@ -202,7 +202,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,25 @@ | |||||||
|  | From 66770a004afe10df11d3902e16eaa0c2c39436bb Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Pawel Dembicki <paweldembicki@gmail.com> | ||||||
|  | Date: Fri, 24 May 2019 17:56:19 +0200 | ||||||
|  | Subject: [PATCH] powerpc: Enable kernel XZ compression option on PPC_85xx | ||||||
|  |  | ||||||
|  | Enable kernel XZ compression option on PPC_85xx. Tested with | ||||||
|  | simpleImage on TP-Link TL-WDR4900 (Freescale P1014 processor). | ||||||
|  |  | ||||||
|  | Suggested-by: Christian Lamparter <chunkeey@gmail.com> | ||||||
|  | Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com> | ||||||
|  | --- | ||||||
|  |  arch/powerpc/Kconfig | 2 +- | ||||||
|  |  1 file changed, 1 insertion(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/arch/powerpc/Kconfig | ||||||
|  | +++ b/arch/powerpc/Kconfig | ||||||
|  | @@ -214,7 +214,7 @@ config PPC | ||||||
|  |  	select HAVE_KERNEL_GZIP | ||||||
|  |  	select HAVE_KERNEL_LZMA			if DEFAULT_UIMAGE | ||||||
|  |  	select HAVE_KERNEL_LZO			if DEFAULT_UIMAGE | ||||||
|  | -	select HAVE_KERNEL_XZ			if PPC_BOOK3S || 44x | ||||||
|  | +	select HAVE_KERNEL_XZ			if PPC_BOOK3S || 44x || PPC_85xx | ||||||
|  |  	select HAVE_KPROBES | ||||||
|  |  	select HAVE_KPROBES_ON_FTRACE | ||||||
|  |  	select HAVE_KRETPROBES | ||||||
							
								
								
									
										313
									
								
								target/linux/generic/pending-5.10/400-mtd-mtdsplit-support.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										313
									
								
								target/linux/generic/pending-5.10/400-mtd-mtdsplit-support.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,313 @@ | |||||||
|  | --- a/drivers/mtd/Kconfig | ||||||
|  | +++ b/drivers/mtd/Kconfig | ||||||
|  | @@ -12,6 +12,25 @@ 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" | ||||||
|  | + | ||||||
|  | +source "drivers/mtd/mtdsplit/Kconfig" | ||||||
|  | + | ||||||
|  | +endmenu | ||||||
|  | + | ||||||
|  |  config MTD_TESTS | ||||||
|  |  	tristate "MTD tests support (DANGEROUS)" | ||||||
|  |  	depends on m | ||||||
|  | --- a/drivers/mtd/mtdpart.c | ||||||
|  | +++ b/drivers/mtd/mtdpart.c | ||||||
|  | @@ -15,10 +15,12 @@ | ||||||
|  |  #include <linux/kmod.h> | ||||||
|  |  #include <linux/mtd/mtd.h> | ||||||
|  |  #include <linux/mtd/partitions.h> | ||||||
|  | +#include <linux/magic.h> | ||||||
|  |  #include <linux/err.h> | ||||||
|  |  #include <linux/of.h> | ||||||
|  |   | ||||||
|  |  #include "mtdcore.h" | ||||||
|  | +#include "mtdsplit/mtdsplit.h" | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  |   * MTD methods which simply translate the effective address and pass through | ||||||
|  | @@ -236,6 +238,146 @@ static int mtd_add_partition_attrs(struc | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static DEFINE_SPINLOCK(part_parser_lock); | ||||||
|  | +static LIST_HEAD(part_parsers); | ||||||
|  | + | ||||||
|  | +static struct mtd_part_parser *mtd_part_parser_get(const char *name) | ||||||
|  | +{ | ||||||
|  | +	struct mtd_part_parser *p, *ret = NULL; | ||||||
|  | + | ||||||
|  | +	spin_lock(&part_parser_lock); | ||||||
|  | + | ||||||
|  | +	list_for_each_entry(p, &part_parsers, list) | ||||||
|  | +		if (!strcmp(p->name, name) && try_module_get(p->owner)) { | ||||||
|  | +			ret = p; | ||||||
|  | +			break; | ||||||
|  | +		} | ||||||
|  | + | ||||||
|  | +	spin_unlock(&part_parser_lock); | ||||||
|  | + | ||||||
|  | +	return ret; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static inline void mtd_part_parser_put(const struct mtd_part_parser *p) | ||||||
|  | +{ | ||||||
|  | +	module_put(p->owner); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +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; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static 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; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int | ||||||
|  | +run_parsers_by_type(struct mtd_info *child, enum mtd_parser_type type) | ||||||
|  | +{ | ||||||
|  | +	struct mtd_partition *parts; | ||||||
|  | +	int nr_parts; | ||||||
|  | +	int i; | ||||||
|  | + | ||||||
|  | +	nr_parts = parse_mtd_partitions_by_type(child, 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 += child->part.offset; | ||||||
|  | + | ||||||
|  | +		mtd_add_partition(child->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 | ||||||
|  | +#define SPLIT_FIRMWARE_NAME	"unused" | ||||||
|  | +#endif | ||||||
|  | + | ||||||
|  | +static void split_firmware(struct mtd_info *master, struct mtd_info *part) | ||||||
|  | +{ | ||||||
|  | +	run_parsers_by_type(part, MTD_PARSER_TYPE_FIRMWARE); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void mtd_partition_split(struct mtd_info *master, struct mtd_info *part) | ||||||
|  | +{ | ||||||
|  | +	static int rootfs_found = 0; | ||||||
|  | + | ||||||
|  | +	if (rootfs_found) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	if (!strcmp(part->name, "rootfs")) { | ||||||
|  | +		run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS); | ||||||
|  | + | ||||||
|  | +		rootfs_found = 1; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	if (IS_ENABLED(CONFIG_MTD_SPLIT_FIRMWARE) && | ||||||
|  | +	    !strcmp(part->name, SPLIT_FIRMWARE_NAME) && | ||||||
|  | +	    !of_find_property(mtd_get_of_node(part), "compatible", NULL)) | ||||||
|  | +		split_firmware(master, part); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  int mtd_add_partition(struct mtd_info *parent, const char *name, | ||||||
|  |  		      long long offset, long long length) | ||||||
|  |  { | ||||||
|  | @@ -274,6 +416,7 @@ int mtd_add_partition(struct mtd_info *p | ||||||
|  |  	if (ret) | ||||||
|  |  		goto err_remove_part; | ||||||
|  |   | ||||||
|  | +	mtd_partition_split(parent, child); | ||||||
|  |  	mtd_add_partition_attrs(child); | ||||||
|  |   | ||||||
|  |  	return 0; | ||||||
|  | @@ -422,6 +565,7 @@ int add_mtd_partitions(struct mtd_info * | ||||||
|  |  			goto err_del_partitions; | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  | +		mtd_partition_split(master, child); | ||||||
|  |  		mtd_add_partition_attrs(child); | ||||||
|  |   | ||||||
|  |  		/* Look for subpartitions */ | ||||||
|  | @@ -438,31 +582,6 @@ err_del_partitions: | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -static DEFINE_SPINLOCK(part_parser_lock); | ||||||
|  | -static LIST_HEAD(part_parsers); | ||||||
|  | - | ||||||
|  | -static struct mtd_part_parser *mtd_part_parser_get(const char *name) | ||||||
|  | -{ | ||||||
|  | -	struct mtd_part_parser *p, *ret = NULL; | ||||||
|  | - | ||||||
|  | -	spin_lock(&part_parser_lock); | ||||||
|  | - | ||||||
|  | -	list_for_each_entry(p, &part_parsers, list) | ||||||
|  | -		if (!strcmp(p->name, name) && try_module_get(p->owner)) { | ||||||
|  | -			ret = p; | ||||||
|  | -			break; | ||||||
|  | -		} | ||||||
|  | - | ||||||
|  | -	spin_unlock(&part_parser_lock); | ||||||
|  | - | ||||||
|  | -	return ret; | ||||||
|  | -} | ||||||
|  | - | ||||||
|  | -static inline void mtd_part_parser_put(const struct mtd_part_parser *p) | ||||||
|  | -{ | ||||||
|  | -	module_put(p->owner); | ||||||
|  | -} | ||||||
|  | - | ||||||
|  |  /* | ||||||
|  |   * Many partition parsers just expected the core to kfree() all their data in | ||||||
|  |   * one chunk. Do that by default. | ||||||
|  | --- a/include/linux/mtd/partitions.h | ||||||
|  | +++ b/include/linux/mtd/partitions.h | ||||||
|  | @@ -75,6 +75,12 @@ struct mtd_part_parser_data { | ||||||
|  |   * Functions dealing with the various ways of partitioning the space | ||||||
|  |   */ | ||||||
|  |   | ||||||
|  | +enum mtd_parser_type { | ||||||
|  | +	MTD_PARSER_TYPE_DEVICE = 0, | ||||||
|  | +	MTD_PARSER_TYPE_ROOTFS, | ||||||
|  | +	MTD_PARSER_TYPE_FIRMWARE, | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  |  struct mtd_part_parser { | ||||||
|  |  	struct list_head list; | ||||||
|  |  	struct module *owner; | ||||||
|  | @@ -83,6 +89,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 */ | ||||||
|  | --- a/drivers/mtd/Makefile | ||||||
|  | +++ b/drivers/mtd/Makefile | ||||||
|  | @@ -9,6 +9,8 @@ mtd-y				:= mtdcore.o mtdsuper.o mtdconc | ||||||
|  |   | ||||||
|  |  obj-y				+= parsers/ | ||||||
|  |   | ||||||
|  | +obj-$(CONFIG_MTD_SPLIT)		+= mtdsplit/ | ||||||
|  | + | ||||||
|  |  # 'Users' - code which presents functionality to userspace. | ||||||
|  |  obj-$(CONFIG_MTD_BLKDEVS)	+= mtd_blkdevs.o | ||||||
|  |  obj-$(CONFIG_MTD_BLOCK)		+= mtdblock.o | ||||||
|  | --- a/include/linux/mtd/mtd.h | ||||||
|  | +++ b/include/linux/mtd/mtd.h | ||||||
|  | @@ -608,6 +608,24 @@ static inline void mtd_align_erase_req(s | ||||||
|  |  		req->len += mtd->erasesize - mod; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +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) | ||||||
|  | @@ -680,6 +698,13 @@ extern void __put_mtd_device(struct mtd_ | ||||||
|  |  extern struct mtd_info *get_mtd_device_nm(const char *name); | ||||||
|  |  extern void put_mtd_device(struct mtd_info *mtd); | ||||||
|  |   | ||||||
|  | +static inline uint64_t mtdpart_get_offset(const struct mtd_info *mtd) | ||||||
|  | +{ | ||||||
|  | +	if (!mtd_is_partition(mtd)) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  | +	return mtd->part.offset; | ||||||
|  | +} | ||||||
|  |   | ||||||
|  |  struct mtd_notifier { | ||||||
|  |  	void (*add)(struct mtd_info *mtd); | ||||||
| @@ -0,0 +1,22 @@ | |||||||
|  | From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> | ||||||
|  | Subject: [PATCH] mtd: redboot: add of_match_table with DT binding | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Type: text/plain; charset=UTF-8 | ||||||
|  | Content-Transfer-Encoding: 8bit | ||||||
|  |  | ||||||
|  | This allows parsing RedBoot compatible partitions for properly described | ||||||
|  | flash device in DT. | ||||||
|  |  | ||||||
|  | Signed-off-by: Rafał Miłecki <rafal@milecki.pl> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/parsers/redboot.c | ||||||
|  | +++ b/drivers/mtd/parsers/redboot.c | ||||||
|  | @@ -300,6 +300,7 @@ static int parse_redboot_partitions(stru | ||||||
|  |   | ||||||
|  |  static const struct of_device_id mtd_parser_redboot_of_match_table[] = { | ||||||
|  |  	{ .compatible = "redboot-fis" }, | ||||||
|  | +	{ .compatible = "ecoscentric,redboot-fis-partitions" }, | ||||||
|  |  	{}, | ||||||
|  |  }; | ||||||
|  |  MODULE_DEVICE_TABLE(of, mtd_parser_redboot_of_match_table); | ||||||
| @@ -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/parsers/redboot.c | ||||||
|  | +++ b/drivers/mtd/parsers/redboot.c | ||||||
|  | @@ -274,14 +274,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,229 @@ | |||||||
|  | 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> | ||||||
|  | [adjust for kernel 5.4, add myloader.c to patch] | ||||||
|  | Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de> | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/parsers/Kconfig | ||||||
|  | +++ b/drivers/mtd/parsers/Kconfig | ||||||
|  | @@ -57,6 +57,22 @@ config MTD_CMDLINE_PARTS | ||||||
|  |   | ||||||
|  |  	  If unsure, say 'N'. | ||||||
|  |   | ||||||
|  | +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. | ||||||
|  | + | ||||||
|  |  config MTD_OF_PARTS | ||||||
|  |  	tristate "OpenFirmware (device tree) partitioning parser" | ||||||
|  |  	default y | ||||||
|  | --- a/drivers/mtd/parsers/Makefile | ||||||
|  | +++ b/drivers/mtd/parsers/Makefile | ||||||
|  | @@ -3,6 +3,7 @@ obj-$(CONFIG_MTD_AR7_PARTS)		+= ar7part. | ||||||
|  |  obj-$(CONFIG_MTD_BCM47XX_PARTS)		+= bcm47xxpart.o | ||||||
|  |  obj-$(CONFIG_MTD_BCM63XX_PARTS)		+= bcm63xxpart.o | ||||||
|  |  obj-$(CONFIG_MTD_CMDLINE_PARTS)		+= cmdlinepart.o | ||||||
|  | +obj-$(CONFIG_MTD_MYLOADER_PARTS)		+= myloader.o | ||||||
|  |  obj-$(CONFIG_MTD_OF_PARTS)		+= ofpart.o | ||||||
|  |  obj-$(CONFIG_MTD_PARSER_IMAGETAG)	+= parser_imagetag.o | ||||||
|  |  obj-$(CONFIG_MTD_AFS_PARTS)		+= afs.o | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/drivers/mtd/parsers/myloader.c | ||||||
|  | @@ -0,0 +1,181 @@ | ||||||
|  | +/* | ||||||
|  | + *  Parse MyLoader-style flash partition tables and produce a Linux partition | ||||||
|  | + *  array to match. | ||||||
|  | + * | ||||||
|  | + *  Copyright (C) 2007-2009 Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | + * | ||||||
|  | + *  This file was based on drivers/mtd/redboot.c | ||||||
|  | + *  Author: Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.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. | ||||||
|  | + */ | ||||||
|  | + | ||||||
|  | +#include <linux/kernel.h> | ||||||
|  | +#include <linux/module.h> | ||||||
|  | +#include <linux/version.h> | ||||||
|  | +#include <linux/slab.h> | ||||||
|  | +#include <linux/init.h> | ||||||
|  | +#include <linux/vmalloc.h> | ||||||
|  | +#include <linux/mtd/mtd.h> | ||||||
|  | +#include <linux/mtd/partitions.h> | ||||||
|  | +#include <linux/byteorder/generic.h> | ||||||
|  | +#include <linux/myloader.h> | ||||||
|  | + | ||||||
|  | +#define BLOCK_LEN_MIN		0x10000 | ||||||
|  | +#define PART_NAME_LEN		32 | ||||||
|  | + | ||||||
|  | +struct part_data { | ||||||
|  | +	struct mylo_partition_table	tab; | ||||||
|  | +	char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN]; | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +static int myloader_parse_partitions(struct mtd_info *master, | ||||||
|  | +				     const struct mtd_partition **pparts, | ||||||
|  | +				     struct mtd_part_parser_data *data) | ||||||
|  | +{ | ||||||
|  | +	struct part_data *buf; | ||||||
|  | +	struct mylo_partition_table *tab; | ||||||
|  | +	struct mylo_partition *part; | ||||||
|  | +	struct mtd_partition *mtd_parts; | ||||||
|  | +	struct mtd_partition *mtd_part; | ||||||
|  | +	int num_parts; | ||||||
|  | +	int ret, i; | ||||||
|  | +	size_t retlen; | ||||||
|  | +	char *names; | ||||||
|  | +	unsigned long offset; | ||||||
|  | +	unsigned long blocklen; | ||||||
|  | + | ||||||
|  | +	buf = vmalloc(sizeof(*buf)); | ||||||
|  | +	if (!buf) { | ||||||
|  | +		return -ENOMEM; | ||||||
|  | +		goto out; | ||||||
|  | +	} | ||||||
|  | +	tab = &buf->tab; | ||||||
|  | + | ||||||
|  | +	blocklen = master->erasesize; | ||||||
|  | +	if (blocklen < BLOCK_LEN_MIN) | ||||||
|  | +		blocklen = BLOCK_LEN_MIN; | ||||||
|  | + | ||||||
|  | +	offset = blocklen; | ||||||
|  | + | ||||||
|  | +	/* Find the partition table */ | ||||||
|  | +	for (i = 0; i < 4; i++, offset += blocklen) { | ||||||
|  | +		printk(KERN_DEBUG "%s: searching for MyLoader partition table" | ||||||
|  | +				" at offset 0x%lx\n", master->name, offset); | ||||||
|  | + | ||||||
|  | +		ret = mtd_read(master, offset, sizeof(*buf), &retlen, | ||||||
|  | +			       (void *)buf); | ||||||
|  | +		if (ret) | ||||||
|  | +			goto out_free_buf; | ||||||
|  | + | ||||||
|  | +		if (retlen != sizeof(*buf)) { | ||||||
|  | +			ret = -EIO; | ||||||
|  | +			goto out_free_buf; | ||||||
|  | +		} | ||||||
|  | + | ||||||
|  | +		/* Check for Partition Table magic number */ | ||||||
|  | +		if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS)) | ||||||
|  | +			break; | ||||||
|  | + | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) { | ||||||
|  | +		printk(KERN_DEBUG "%s: no MyLoader partition table found\n", | ||||||
|  | +			master->name); | ||||||
|  | +		ret = 0; | ||||||
|  | +		goto out_free_buf; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	/* The MyLoader and the Partition Table is always present */ | ||||||
|  | +	num_parts = 2; | ||||||
|  | + | ||||||
|  | +	/* Detect number of used partitions */ | ||||||
|  | +	for (i = 0; i < MYLO_MAX_PARTITIONS; i++) { | ||||||
|  | +		part = &tab->partitions[i]; | ||||||
|  | + | ||||||
|  | +		if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE) | ||||||
|  | +			continue; | ||||||
|  | + | ||||||
|  | +		num_parts++; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) + | ||||||
|  | +				num_parts * PART_NAME_LEN), GFP_KERNEL); | ||||||
|  | + | ||||||
|  | +	if (!mtd_parts) { | ||||||
|  | +		ret = -ENOMEM; | ||||||
|  | +		goto out_free_buf; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	mtd_part = mtd_parts; | ||||||
|  | +	names = (char *)&mtd_parts[num_parts]; | ||||||
|  | + | ||||||
|  | +	strncpy(names, "myloader", PART_NAME_LEN); | ||||||
|  | +	mtd_part->name = names; | ||||||
|  | +	mtd_part->offset = 0; | ||||||
|  | +	mtd_part->size = offset; | ||||||
|  | +	mtd_part->mask_flags = MTD_WRITEABLE; | ||||||
|  | +	mtd_part++; | ||||||
|  | +	names += PART_NAME_LEN; | ||||||
|  | + | ||||||
|  | +	strncpy(names, "partition_table", PART_NAME_LEN); | ||||||
|  | +	mtd_part->name = names; | ||||||
|  | +	mtd_part->offset = offset; | ||||||
|  | +	mtd_part->size = blocklen; | ||||||
|  | +	mtd_part->mask_flags = MTD_WRITEABLE; | ||||||
|  | +	mtd_part++; | ||||||
|  | +	names += PART_NAME_LEN; | ||||||
|  | + | ||||||
|  | +	for (i = 0; i < MYLO_MAX_PARTITIONS; i++) { | ||||||
|  | +		part = &tab->partitions[i]; | ||||||
|  | + | ||||||
|  | +		if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE) | ||||||
|  | +			continue; | ||||||
|  | + | ||||||
|  | +		if ((buf->names[i][0]) && (buf->names[i][0] != '\xff')) | ||||||
|  | +			strncpy(names, buf->names[i], PART_NAME_LEN); | ||||||
|  | +		else | ||||||
|  | +			snprintf(names, PART_NAME_LEN, "partition%d", i); | ||||||
|  | + | ||||||
|  | +		mtd_part->offset = le32_to_cpu(part->addr); | ||||||
|  | +		mtd_part->size = le32_to_cpu(part->size); | ||||||
|  | +		mtd_part->name = names; | ||||||
|  | +		mtd_part++; | ||||||
|  | +		names += PART_NAME_LEN; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	*pparts = mtd_parts; | ||||||
|  | +	ret = num_parts; | ||||||
|  | + | ||||||
|  | + out_free_buf: | ||||||
|  | +	vfree(buf); | ||||||
|  | + out: | ||||||
|  | +	return ret; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static struct mtd_part_parser myloader_mtd_parser = { | ||||||
|  | +	.owner		= THIS_MODULE, | ||||||
|  | +	.parse_fn	= myloader_parse_partitions, | ||||||
|  | +	.name		= "MyLoader", | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +static int __init myloader_mtd_parser_init(void) | ||||||
|  | +{ | ||||||
|  | +	register_mtd_parser(&myloader_mtd_parser); | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void __exit myloader_mtd_parser_exit(void) | ||||||
|  | +{ | ||||||
|  | +	deregister_mtd_parser(&myloader_mtd_parser); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +module_init(myloader_mtd_parser_init); | ||||||
|  | +module_exit(myloader_mtd_parser_exit); | ||||||
|  | + | ||||||
|  | +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); | ||||||
|  | +MODULE_DESCRIPTION("Parsing code for MyLoader partition tables"); | ||||||
|  | +MODULE_LICENSE("GPL v2"); | ||||||
| @@ -0,0 +1,68 @@ | |||||||
|  | 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 | ||||||
|  | @@ -25,6 +25,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) | ||||||
|  |  { | ||||||
|  | @@ -79,21 +106,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]); | ||||||
|  | +		part->name = parser_trx_data_part_name(mtd, part->offset); | ||||||
|  |  		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/parsers/bcm47xxpart.c | ||||||
|  | +++ b/drivers/mtd/parsers/bcm47xxpart.c | ||||||
|  | @@ -35,6 +35,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 | ||||||
|  | @@ -178,6 +179,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) { | ||||||
| @@ -0,0 +1,38 @@ | |||||||
|  | From 4437e01fb6bca63fccdba5d6c44888b0935885c2 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= <hacks@slashdirt.org> | ||||||
|  | Date: Tue, 24 Mar 2020 11:45:07 +0100 | ||||||
|  | Subject: [PATCH] generic: routerboot partition build bits (5.4) | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Type: text/plain; charset=UTF-8 | ||||||
|  | Content-Transfer-Encoding: 8bit | ||||||
|  |  | ||||||
|  | This patch adds routerbootpart kernel build bits | ||||||
|  |  | ||||||
|  | Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/parsers/Kconfig  | 9 +++++++++ | ||||||
|  |  drivers/mtd/parsers/Makefile | 1 + | ||||||
|  |  2 files changed, 10 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/parsers/Kconfig | ||||||
|  | +++ b/drivers/mtd/parsers/Kconfig | ||||||
|  | @@ -176,3 +176,12 @@ config MTD_REDBOOT_PARTS_READONLY | ||||||
|  |  	  'FIS directory' images, enable this option. | ||||||
|  |   | ||||||
|  |  endif # MTD_REDBOOT_PARTS | ||||||
|  | + | ||||||
|  | +config MTD_ROUTERBOOT_PARTS | ||||||
|  | +	tristate "RouterBoot flash partition parser" | ||||||
|  | +	depends on MTD && OF | ||||||
|  | +	help | ||||||
|  | +	 MikroTik RouterBoot is implemented as a multi segment system on the | ||||||
|  | +	 flash, some of which are fixed and some of which are located at | ||||||
|  | +	 variable offsets. This parser handles both cases via properly | ||||||
|  | +	 formatted DTS. | ||||||
|  | --- a/drivers/mtd/parsers/Makefile | ||||||
|  | +++ b/drivers/mtd/parsers/Makefile | ||||||
|  | @@ -10,3 +10,4 @@ obj-$(CONFIG_MTD_AFS_PARTS)		+= afs.o | ||||||
|  |  obj-$(CONFIG_MTD_PARSER_TRX)		+= parser_trx.o | ||||||
|  |  obj-$(CONFIG_MTD_SHARPSL_PARTS)		+= sharpslpart.o | ||||||
|  |  obj-$(CONFIG_MTD_REDBOOT_PARTS)		+= redboot.o | ||||||
|  | +obj-$(CONFIG_MTD_ROUTERBOOT_PARTS)		+= routerbootpart.o | ||||||
| @@ -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 | ||||||
|  | @@ -909,7 +909,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 | ||||||
|  | @@ -2053,6 +2053,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/macronix.c | ||||||
|  | +++ b/drivers/mtd/spi-nor/macronix.c | ||||||
|  | @@ -96,6 +96,7 @@ static void macronix_default_init(struct | ||||||
|  |  { | ||||||
|  |  	nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable; | ||||||
|  |  	nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode; | ||||||
|  | +	nor->flags |= SNOR_F_HAS_LOCK; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static const struct spi_nor_fixups macronix_fixups = { | ||||||
| @@ -0,0 +1,71 @@ | |||||||
|  | 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 | ||||||
|  | @@ -24,6 +24,17 @@ config MTD_SPI_NOR_USE_4K_SECTORS | ||||||
|  |  	  Please note that some tools/drivers/filesystems may not work with | ||||||
|  |  	  4096 B erase size (e.g. UBIFS requires 15 KiB as a minimum). | ||||||
|  |   | ||||||
|  | +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. | ||||||
|  | + | ||||||
|  |  source "drivers/mtd/spi-nor/controllers/Kconfig" | ||||||
|  |   | ||||||
|  |  endif # MTD_SPI_NOR | ||||||
|  | --- a/drivers/mtd/spi-nor/core.c | ||||||
|  | +++ b/drivers/mtd/spi-nor/core.c | ||||||
|  | @@ -2784,6 +2784,21 @@ static void spi_nor_info_init_params(str | ||||||
|  |  	 */ | ||||||
|  |  	erase_mask = 0; | ||||||
|  |  	i = 0; | ||||||
|  | +#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS | ||||||
|  | +	if ((info->flags & SECT_4K_PMC) && (params->size <= | ||||||
|  | +		   CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT * 1024)) { | ||||||
|  | +		erase_mask |= BIT(i); | ||||||
|  | +		spi_nor_set_erase_type(&map->erase_type[i], 4096u, | ||||||
|  | +				       SPINOR_OP_BE_4K_PMC); | ||||||
|  | +		i++; | ||||||
|  | +	} else if ((info->flags & SECT_4K) && (params->size <= | ||||||
|  | +	    CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT * 1024)) { | ||||||
|  | +		erase_mask |= BIT(i); | ||||||
|  | +		spi_nor_set_erase_type(&map->erase_type[i], 4096u, | ||||||
|  | +				       SPINOR_OP_BE_4K); | ||||||
|  | +		i++; | ||||||
|  | +	} | ||||||
|  | +#else | ||||||
|  |  	if (info->flags & SECT_4K_PMC) { | ||||||
|  |  		erase_mask |= BIT(i); | ||||||
|  |  		spi_nor_set_erase_type(&map->erase_type[i], 4096u, | ||||||
|  | @@ -2795,6 +2810,7 @@ static void spi_nor_info_init_params(str | ||||||
|  |  				       SPINOR_OP_BE_4K); | ||||||
|  |  		i++; | ||||||
|  |  	} | ||||||
|  | +#endif | ||||||
|  |  	erase_mask |= BIT(i); | ||||||
|  |  	spi_nor_set_erase_type(&map->erase_type[i], info->sector_size, | ||||||
|  |  			       SPINOR_OP_SE); | ||||||
| @@ -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/eon.c | ||||||
|  | +++ b/drivers/mtd/spi-nor/eon.c | ||||||
|  | @@ -15,6 +15,7 @@ static const struct flash_info eon_parts | ||||||
|  |  	{ "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) }, | ||||||
|  |  	{ "en25q80a",   INFO(0x1c3014, 0, 64 * 1024,   16, | ||||||
|  |  			     SECT_4K | SPI_NOR_DUAL_READ) }, | ||||||
|  |  	{ "en25qh16",   INFO(0x1c7015, 0, 64 * 1024,   32, | ||||||
| @@ -0,0 +1,79 @@ | |||||||
|  | From patchwork Thu Feb  6 17:19:41 2020 | ||||||
|  | Content-Type: text/plain; charset="utf-8" | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Transfer-Encoding: 7bit | ||||||
|  | X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org> | ||||||
|  | X-Patchwork-Id: 1234465 | ||||||
|  | Date: Thu, 6 Feb 2020 19:19:41 +0200 | ||||||
|  | From: Daniel Golle <daniel@makrotopia.org> | ||||||
|  | To: linux-mtd@lists.infradead.org | ||||||
|  | Subject: [PATCH v2] mtd: spi-nor: Add support for xt25f128b chip | ||||||
|  | Message-ID: <20200206171941.GA2398@makrotopia.org> | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Disposition: inline | ||||||
|  | List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-mtd>, | ||||||
|  |  <mailto:linux-mtd-request@lists.infradead.org?subject=subscribe> | ||||||
|  | Cc: Eitan Cohen <eitan@neot-semadar.com>, Piotr Dymacz <pepe2k@gmail.com>, | ||||||
|  |  Tudor Ambarus <tudor.ambarus@microchip.com> | ||||||
|  | Sender: "linux-mtd" <linux-mtd-bounces@lists.infradead.org> | ||||||
|  | Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org | ||||||
|  |  | ||||||
|  | Add XT25F128B made by XTX Technology (Shenzhen) Limited. | ||||||
|  | This chip supports dual and quad read and uniform 4K-byte erase. | ||||||
|  | Verified on Teltonika RUT955 which comes with XT25F128B in recent | ||||||
|  | versions of the device. | ||||||
|  |  | ||||||
|  | Signed-off-by: Daniel Golle <daniel@makrotopia.org> | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/spi-nor/spi-nor.c | 4 ++++ | ||||||
|  |  1 file changed, 4 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/spi-nor/Makefile | ||||||
|  | +++ b/drivers/mtd/spi-nor/Makefile | ||||||
|  | @@ -17,6 +17,7 @@ spi-nor-objs			+= sst.o | ||||||
|  |  spi-nor-objs			+= winbond.o | ||||||
|  |  spi-nor-objs			+= xilinx.o | ||||||
|  |  spi-nor-objs			+= xmc.o | ||||||
|  | +spi-nor-objs			+= xtx.o | ||||||
|  |  obj-$(CONFIG_MTD_SPI_NOR)	+= spi-nor.o | ||||||
|  |   | ||||||
|  |  obj-$(CONFIG_MTD_SPI_NOR)	+= controllers/ | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/drivers/mtd/spi-nor/xtx.c | ||||||
|  | @@ -0,0 +1,15 @@ | ||||||
|  | +// SPDX-License-Identifier: GPL-2.0 | ||||||
|  | +#include <linux/mtd/spi-nor.h> | ||||||
|  | + | ||||||
|  | +#include "core.h" | ||||||
|  | + | ||||||
|  | +static const struct flash_info xtx_parts[] = { | ||||||
|  | +	/* XTX Technology (Shenzhen) Limited */ | ||||||
|  | +	{ "xt25f128b", INFO(0x0B4018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +const struct spi_nor_manufacturer spi_nor_xtx = { | ||||||
|  | +	.name = "xtx", | ||||||
|  | +	.parts = xtx_parts, | ||||||
|  | +	.nparts = ARRAY_SIZE(xtx_parts), | ||||||
|  | +}; | ||||||
|  | --- a/drivers/mtd/spi-nor/core.c | ||||||
|  | +++ b/drivers/mtd/spi-nor/core.c | ||||||
|  | @@ -2024,6 +2024,7 @@ static const struct spi_nor_manufacturer | ||||||
|  |  	&spi_nor_winbond, | ||||||
|  |  	&spi_nor_xilinx, | ||||||
|  |  	&spi_nor_xmc, | ||||||
|  | +	&spi_nor_xtx, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  static const struct flash_info * | ||||||
|  | --- a/drivers/mtd/spi-nor/core.h | ||||||
|  | +++ b/drivers/mtd/spi-nor/core.h | ||||||
|  | @@ -398,6 +398,7 @@ extern const struct spi_nor_manufacturer | ||||||
|  |  extern const struct spi_nor_manufacturer spi_nor_winbond; | ||||||
|  |  extern const struct spi_nor_manufacturer spi_nor_xilinx; | ||||||
|  |  extern const struct spi_nor_manufacturer spi_nor_xmc; | ||||||
|  | +extern const struct spi_nor_manufacturer spi_nor_xtx; | ||||||
|  |   | ||||||
|  |  int spi_nor_write_enable(struct spi_nor *nor); | ||||||
|  |  int spi_nor_write_disable(struct spi_nor *nor); | ||||||
| @@ -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 | ||||||
|  | @@ -27,6 +27,7 @@ | ||||||
|  |  #include <linux/reboot.h> | ||||||
|  |  #include <linux/leds.h> | ||||||
|  |  #include <linux/debugfs.h> | ||||||
|  | +#include <linux/root_dev.h> | ||||||
|  |  #include <linux/nvmem-provider.h> | ||||||
|  |   | ||||||
|  |  #include <linux/mtd/mtd.h> | ||||||
|  | @@ -692,6 +693,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_nvmem_add: | ||||||
| @@ -0,0 +1,180 @@ | |||||||
|  | From ea92cbb50a78404e29de2cc3999a240615ffb1c8 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Chuanhong Guo <gch981213@gmail.com> | ||||||
|  | Date: Mon, 6 Apr 2020 17:58:48 +0800 | ||||||
|  | Subject: [PATCH] mtd: spi-nor: rework broken-flash-reset support | ||||||
|  |  | ||||||
|  | Instead of resetting flash to 3B address on remove hook, this | ||||||
|  | implementation only enters 4B mode when needed, which prevents | ||||||
|  | more unexpected reboot stuck. This implementation makes it only | ||||||
|  | break when a kernel panic happens during flash operation on 16M+ | ||||||
|  | areas. | ||||||
|  | *OpenWrt only*: silent broken-flash-reset warning. We are not dealing | ||||||
|  | with vendors and it's unpleasant for users to se that unnecessary | ||||||
|  | and long WARN_ON print. | ||||||
|  |  | ||||||
|  | Signed-off-by: Chuanhong Guo <gch981213@gmail.com> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/spi-nor/spi-nor.c | 52 +++++++++++++++++++++++++++++++++-- | ||||||
|  |  1 file changed, 49 insertions(+), 3 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/spi-nor/core.c | ||||||
|  | +++ b/drivers/mtd/spi-nor/core.c | ||||||
|  | @@ -1445,6 +1445,23 @@ destroy_erase_cmd_list: | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +int spi_nor_check_set_addr_width(struct spi_nor *nor, loff_t addr) | ||||||
|  | +{ | ||||||
|  | +	u8 addr_width; | ||||||
|  | + | ||||||
|  | +	if ((nor->flags & (SNOR_F_4B_OPCODES | SNOR_F_BROKEN_RESET)) != | ||||||
|  | +	    SNOR_F_BROKEN_RESET) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  | +	addr_width = addr & 0xff000000 ? 4 : 3; | ||||||
|  | +	if (nor->addr_width == addr_width) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  | +	nor->addr_width = addr_width; | ||||||
|  | + | ||||||
|  | +	return nor->params->set_4byte_addr_mode(nor, addr_width == 4); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  /* | ||||||
|  |   * Erase an address range on the nor chip.  The address range may extend | ||||||
|  |   * one or more erase sectors.  Return an error is there is a problem erasing. | ||||||
|  | @@ -1472,6 +1489,10 @@ static int spi_nor_erase(struct mtd_info | ||||||
|  |  	if (ret) | ||||||
|  |  		return ret; | ||||||
|  |   | ||||||
|  | +	ret = spi_nor_check_set_addr_width(nor, instr->addr + instr->len); | ||||||
|  | +	if (ret < 0) | ||||||
|  | +		return ret; | ||||||
|  | + | ||||||
|  |  	/* whole-chip erase? */ | ||||||
|  |  	if (len == mtd->size && !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) { | ||||||
|  |  		unsigned long timeout; | ||||||
|  | @@ -1531,6 +1552,7 @@ static int spi_nor_erase(struct mtd_info | ||||||
|  |  	ret = spi_nor_write_disable(nor); | ||||||
|  |   | ||||||
|  |  erase_err: | ||||||
|  | +	spi_nor_check_set_addr_width(nor, 0); | ||||||
|  |  	spi_nor_unlock_and_unprep(nor); | ||||||
|  |   | ||||||
|  |  	return ret; | ||||||
|  | @@ -1870,7 +1892,9 @@ static int spi_nor_lock(struct mtd_info | ||||||
|  |  	if (ret) | ||||||
|  |  		return ret; | ||||||
|  |   | ||||||
|  | +	spi_nor_check_set_addr_width(nor, ofs + len); | ||||||
|  |  	ret = nor->params->locking_ops->lock(nor, ofs, len); | ||||||
|  | +	spi_nor_check_set_addr_width(nor, 0); | ||||||
|  |   | ||||||
|  |  	spi_nor_unlock_and_unprep(nor); | ||||||
|  |  	return ret; | ||||||
|  | @@ -1885,7 +1909,9 @@ static int spi_nor_unlock(struct mtd_inf | ||||||
|  |  	if (ret) | ||||||
|  |  		return ret; | ||||||
|  |   | ||||||
|  | +	spi_nor_check_set_addr_width(nor, ofs + len); | ||||||
|  |  	ret = nor->params->locking_ops->unlock(nor, ofs, len); | ||||||
|  | +	spi_nor_check_set_addr_width(nor, 0); | ||||||
|  |   | ||||||
|  |  	spi_nor_unlock_and_unprep(nor); | ||||||
|  |  	return ret; | ||||||
|  | @@ -1900,7 +1926,9 @@ static int spi_nor_is_locked(struct mtd_ | ||||||
|  |  	if (ret) | ||||||
|  |  		return ret; | ||||||
|  |   | ||||||
|  | +	spi_nor_check_set_addr_width(nor, ofs + len); | ||||||
|  |  	ret = nor->params->locking_ops->is_locked(nor, ofs, len); | ||||||
|  | +	spi_nor_check_set_addr_width(nor, 0); | ||||||
|  |   | ||||||
|  |  	spi_nor_unlock_and_unprep(nor); | ||||||
|  |  	return ret; | ||||||
|  | @@ -2093,6 +2121,10 @@ static int spi_nor_read(struct mtd_info | ||||||
|  |  	if (ret) | ||||||
|  |  		return ret; | ||||||
|  |   | ||||||
|  | +	ret = spi_nor_check_set_addr_width(nor, from + len); | ||||||
|  | +	if (ret < 0) | ||||||
|  | +		return ret; | ||||||
|  | + | ||||||
|  |  	while (len) { | ||||||
|  |  		loff_t addr = from; | ||||||
|  |   | ||||||
|  | @@ -2116,6 +2148,7 @@ static int spi_nor_read(struct mtd_info | ||||||
|  |  	ret = 0; | ||||||
|  |   | ||||||
|  |  read_err: | ||||||
|  | +	spi_nor_check_set_addr_width(nor, 0); | ||||||
|  |  	spi_nor_unlock_and_unprep(nor); | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  | @@ -2138,6 +2171,10 @@ static int spi_nor_write(struct mtd_info | ||||||
|  |  	if (ret) | ||||||
|  |  		return ret; | ||||||
|  |   | ||||||
|  | +	ret = spi_nor_check_set_addr_width(nor, to + len); | ||||||
|  | +	if (ret < 0) | ||||||
|  | +		return ret; | ||||||
|  | + | ||||||
|  |  	for (i = 0; i < len; ) { | ||||||
|  |  		ssize_t written; | ||||||
|  |  		loff_t addr = to + i; | ||||||
|  | @@ -2180,6 +2217,7 @@ static int spi_nor_write(struct mtd_info | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  write_err: | ||||||
|  | +	spi_nor_check_set_addr_width(nor, 0); | ||||||
|  |  	spi_nor_unlock_and_unprep(nor); | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
|  | @@ -2975,9 +3013,13 @@ static int spi_nor_init(struct spi_nor * | ||||||
|  |  		 * reboots (e.g., crashes). Warn the user (or hopefully, system | ||||||
|  |  		 * designer) that this is bad. | ||||||
|  |  		 */ | ||||||
|  | -		WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET, | ||||||
|  | -			  "enabling reset hack; may not recover from unexpected reboots\n"); | ||||||
|  | -		nor->params->set_4byte_addr_mode(nor, true); | ||||||
|  | +		if (nor->flags & SNOR_F_BROKEN_RESET) { | ||||||
|  | +			dev_warn(nor->dev, | ||||||
|  | +				"enabling reset hack; may not recover from unexpected reboots\n"); | ||||||
|  | +			nor->addr_width = 3; | ||||||
|  | +		} else { | ||||||
|  | +			nor->params->set_4byte_addr_mode(nor, true); | ||||||
|  | +		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	return 0; | ||||||
|  | --- a/drivers/mtd/spi-nor/core.h | ||||||
|  | +++ b/drivers/mtd/spi-nor/core.h | ||||||
|  | @@ -400,6 +400,7 @@ extern const struct spi_nor_manufacturer | ||||||
|  |  extern const struct spi_nor_manufacturer spi_nor_xmc; | ||||||
|  |  extern const struct spi_nor_manufacturer spi_nor_xtx; | ||||||
|  |   | ||||||
|  | +int spi_nor_check_set_addr_width(struct spi_nor *nor, loff_t addr); | ||||||
|  |  int spi_nor_write_enable(struct spi_nor *nor); | ||||||
|  |  int spi_nor_write_disable(struct spi_nor *nor); | ||||||
|  |  int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable); | ||||||
|  | --- a/drivers/mtd/spi-nor/sst.c | ||||||
|  | +++ b/drivers/mtd/spi-nor/sst.c | ||||||
|  | @@ -55,6 +55,10 @@ static int sst_write(struct mtd_info *mt | ||||||
|  |  	if (ret) | ||||||
|  |  		return ret; | ||||||
|  |   | ||||||
|  | +	ret = spi_nor_check_set_addr_width(nor, to + len); | ||||||
|  | +	if (ret < 0) | ||||||
|  | +		return ret; | ||||||
|  | + | ||||||
|  |  	ret = spi_nor_write_enable(nor); | ||||||
|  |  	if (ret) | ||||||
|  |  		goto out; | ||||||
|  | @@ -124,6 +128,7 @@ static int sst_write(struct mtd_info *mt | ||||||
|  |  	} | ||||||
|  |  out: | ||||||
|  |  	*retlen += actual; | ||||||
|  | +	spi_nor_check_set_addr_width(nor, 0); | ||||||
|  |  	spi_nor_unlock_and_unprep(nor); | ||||||
|  |  	return ret; | ||||||
|  |  } | ||||||
| @@ -0,0 +1,22 @@ | |||||||
|  | From d68b4aa22e8c625685bfad642dd7337948dc0ad1 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Koen Vandeputte <koen.vandeputte@ncentric.com> | ||||||
|  | Date: Mon, 6 Jan 2020 13:07:56 +0100 | ||||||
|  | Subject: [PATCH] mtd: spi-nor: add support for Gigadevice GD25D05 | ||||||
|  |  | ||||||
|  | Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/spi-nor/spi-nor.c | 5 +++++ | ||||||
|  |  1 file changed, 5 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/spi-nor/gigadevice.c | ||||||
|  | +++ b/drivers/mtd/spi-nor/gigadevice.c | ||||||
|  | @@ -24,6 +24,9 @@ static struct spi_nor_fixups gd25q256_fi | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  static const struct flash_info gigadevice_parts[] = { | ||||||
|  | +	{ "gd25q05", INFO(0xc84010, 0, 64 * 1024,  1, | ||||||
|  | +			  SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | | ||||||
|  | +			  SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, | ||||||
|  |  	{ "gd25q16", INFO(0xc84015, 0, 64 * 1024,  32, | ||||||
|  |  			  SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | | ||||||
|  |  			  SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, | ||||||
| @@ -0,0 +1,97 @@ | |||||||
|  | From: Daniel Golle <daniel@makrotopia.org> | ||||||
|  | Subject: ubi: auto-attach mtd device named "ubi" or "data" on boot | ||||||
|  |  | ||||||
|  | Signed-off-by: Daniel Golle <daniel@makrotopia.org> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/ubi/build.c | 36 ++++++++++++++++++++++++++++++++++++ | ||||||
|  |  1 file changed, 36 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/ubi/build.c | ||||||
|  | +++ b/drivers/mtd/ubi/build.c | ||||||
|  | @@ -1192,6 +1192,73 @@ static struct mtd_info * __init open_mtd | ||||||
|  |  	return mtd; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +/* | ||||||
|  | + * This function tries attaching mtd partitions named either "ubi" or "data" | ||||||
|  | + * during boot. | ||||||
|  | + */ | ||||||
|  | +static void __init ubi_auto_attach(void) | ||||||
|  | +{ | ||||||
|  | +	int err; | ||||||
|  | +	struct mtd_info *mtd; | ||||||
|  | +	loff_t offset = 0; | ||||||
|  | +	size_t len; | ||||||
|  | +	char magic[4]; | ||||||
|  | + | ||||||
|  | +	/* try attaching mtd device named "ubi" or "data" */ | ||||||
|  | +	mtd = open_mtd_device("ubi"); | ||||||
|  | +	if (IS_ERR(mtd)) | ||||||
|  | +		mtd = open_mtd_device("data"); | ||||||
|  | + | ||||||
|  | +	if (IS_ERR(mtd)) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	/* get the first not bad block */ | ||||||
|  | +	if (mtd_can_have_bb(mtd)) | ||||||
|  | +		while (mtd_block_isbad(mtd, offset)) { | ||||||
|  | +			offset += mtd->erasesize; | ||||||
|  | + | ||||||
|  | +			if (offset > mtd->size) { | ||||||
|  | +				pr_err("UBI error: Failed to find a non-bad " | ||||||
|  | +				       "block on mtd%d\n", mtd->index); | ||||||
|  | +				goto cleanup; | ||||||
|  | +			} | ||||||
|  | +		} | ||||||
|  | + | ||||||
|  | +	/* check if the read from flash was successful */ | ||||||
|  | +	err = mtd_read(mtd, offset, 4, &len, (void *) magic); | ||||||
|  | +	if ((err && !mtd_is_bitflip(err)) || len != 4) { | ||||||
|  | +		pr_err("UBI error: unable to read from mtd%d\n", mtd->index); | ||||||
|  | +		goto cleanup; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	/* check for a valid ubi magic */ | ||||||
|  | +	if (strncmp(magic, "UBI#", 4)) { | ||||||
|  | +		pr_err("UBI error: no valid UBI magic found inside mtd%d\n", mtd->index); | ||||||
|  | +		goto cleanup; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	/* don't auto-add media types where UBI doesn't makes sense */ | ||||||
|  | +	if (mtd->type != MTD_NANDFLASH && | ||||||
|  | +	    mtd->type != MTD_NORFLASH && | ||||||
|  | +	    mtd->type != MTD_DATAFLASH && | ||||||
|  | +	    mtd->type != MTD_MLCNANDFLASH) | ||||||
|  | +		goto cleanup; | ||||||
|  | + | ||||||
|  | +	mutex_lock(&ubi_devices_mutex); | ||||||
|  | +	pr_notice("UBI: auto-attach mtd%d\n", mtd->index); | ||||||
|  | +	err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0); | ||||||
|  | +	mutex_unlock(&ubi_devices_mutex); | ||||||
|  | +	if (err < 0) { | ||||||
|  | +		pr_err("UBI error: cannot attach mtd%d\n", mtd->index); | ||||||
|  | +		goto cleanup; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return; | ||||||
|  | + | ||||||
|  | +cleanup: | ||||||
|  | +	put_mtd_device(mtd); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static int __init ubi_init(void) | ||||||
|  |  { | ||||||
|  |  	int err, i, k; | ||||||
|  | @@ -1275,6 +1342,12 @@ static int __init ubi_init(void) | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	/* auto-attach mtd devices only if built-in to the kernel and no ubi.mtd | ||||||
|  | +	 * parameter was given */ | ||||||
|  | +	if (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && | ||||||
|  | +	    !ubi_is_module() && !mtd_devs) | ||||||
|  | +		ubi_auto_attach(); | ||||||
|  | + | ||||||
|  |  	err = ubiblock_init(); | ||||||
|  |  	if (err) { | ||||||
|  |  		pr_err("UBI error: block: cannot initialize, error %d\n", err); | ||||||
| @@ -0,0 +1,66 @@ | |||||||
|  | From: Daniel Golle <daniel@makrotopia.org> | ||||||
|  | Subject: ubi: auto-create ubiblock device for rootfs | ||||||
|  |  | ||||||
|  | Signed-off-by: Daniel Golle <daniel@makrotopia.org> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/ubi/block.c | 42 ++++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  1 file changed, 42 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/ubi/block.c | ||||||
|  | +++ b/drivers/mtd/ubi/block.c | ||||||
|  | @@ -652,6 +652,44 @@ static void __init ubiblock_create_from_ | ||||||
|  |  	} | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +#define UBIFS_NODE_MAGIC  0x06101831 | ||||||
|  | +static inline int ubi_vol_is_ubifs(struct ubi_volume_desc *desc) | ||||||
|  | +{ | ||||||
|  | +	int ret; | ||||||
|  | +	uint32_t magic_of, magic; | ||||||
|  | +	ret = ubi_read(desc, 0, (char *)&magic_of, 0, 4); | ||||||
|  | +	if (ret) | ||||||
|  | +		return 0; | ||||||
|  | +	magic = le32_to_cpu(magic_of); | ||||||
|  | +	return magic == UBIFS_NODE_MAGIC; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static void __init ubiblock_create_auto_rootfs(void) | ||||||
|  | +{ | ||||||
|  | +	int ubi_num, ret, is_ubifs; | ||||||
|  | +	struct ubi_volume_desc *desc; | ||||||
|  | +	struct ubi_volume_info vi; | ||||||
|  | + | ||||||
|  | +	for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) { | ||||||
|  | +		desc = ubi_open_volume_nm(ubi_num, "rootfs", UBI_READONLY); | ||||||
|  | +		if (IS_ERR(desc)) | ||||||
|  | +			continue; | ||||||
|  | + | ||||||
|  | +		ubi_get_volume_info(desc, &vi); | ||||||
|  | +		is_ubifs = ubi_vol_is_ubifs(desc); | ||||||
|  | +		ubi_close_volume(desc); | ||||||
|  | +		if (is_ubifs) | ||||||
|  | +			break; | ||||||
|  | + | ||||||
|  | +		ret = ubiblock_create(&vi); | ||||||
|  | +		if (ret) | ||||||
|  | +			pr_err("UBI error: block: can't add '%s' volume, err=%d\n", | ||||||
|  | +				vi.name, ret); | ||||||
|  | +		/* always break if we get here */ | ||||||
|  | +		break; | ||||||
|  | +	} | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static void ubiblock_remove_all(void) | ||||||
|  |  { | ||||||
|  |  	struct ubiblock *next; | ||||||
|  | @@ -684,6 +722,10 @@ int __init ubiblock_init(void) | ||||||
|  |  	 */ | ||||||
|  |  	ubiblock_create_from_param(); | ||||||
|  |   | ||||||
|  | +	/* auto-attach "rootfs" volume if existing and non-ubifs */ | ||||||
|  | +	if (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV)) | ||||||
|  | +		ubiblock_create_auto_rootfs(); | ||||||
|  | + | ||||||
|  |  	/* | ||||||
|  |  	 * Block devices are only created upon user requests, so we ignore | ||||||
|  |  	 * existing volumes. | ||||||
| @@ -0,0 +1,51 @@ | |||||||
|  | From: Daniel Golle <daniel@makrotopia.org> | ||||||
|  | Subject: try auto-mounting ubi0:rootfs in init/do_mounts.c | ||||||
|  |  | ||||||
|  | Signed-off-by: Daniel Golle <daniel@makrotopia.org> | ||||||
|  | --- | ||||||
|  |  init/do_mounts.c | 26 +++++++++++++++++++++++++- | ||||||
|  |  1 file changed, 25 insertions(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/init/do_mounts.c | ||||||
|  | +++ b/init/do_mounts.c | ||||||
|  | @@ -474,7 +474,28 @@ retry: | ||||||
|  |  out: | ||||||
|  |  	put_page(page); | ||||||
|  |  } | ||||||
|  | -  | ||||||
|  | + | ||||||
|  | +static int __init mount_ubi_rootfs(void) | ||||||
|  | +{ | ||||||
|  | +	int flags = MS_SILENT; | ||||||
|  | +	int err, tried = 0; | ||||||
|  | + | ||||||
|  | +	while (tried < 2) { | ||||||
|  | +		err = do_mount_root("ubi0:rootfs", "ubifs", flags, \ | ||||||
|  | +					root_mount_data); | ||||||
|  | +		switch (err) { | ||||||
|  | +			case -EACCES: | ||||||
|  | +				flags |= MS_RDONLY; | ||||||
|  | +				tried++; | ||||||
|  | +				break; | ||||||
|  | +			default: | ||||||
|  | +				return err; | ||||||
|  | +		} | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return -EINVAL; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  #ifdef CONFIG_ROOT_NFS | ||||||
|  |   | ||||||
|  |  #define NFSROOT_TIMEOUT_MIN	5 | ||||||
|  | @@ -567,6 +588,10 @@ void __init mount_root(void) | ||||||
|  |  		return; | ||||||
|  |  	} | ||||||
|  |  #endif | ||||||
|  | +#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV | ||||||
|  | +	if (!mount_ubi_rootfs()) | ||||||
|  | +		return; | ||||||
|  | +#endif | ||||||
|  |  #ifdef CONFIG_BLOCK | ||||||
|  |  	{ | ||||||
|  |  		int err = create_dev("/dev/root", ROOT_DEV); | ||||||
| @@ -0,0 +1,34 @@ | |||||||
|  | From: Daniel Golle <daniel@makrotopia.org> | ||||||
|  | Subject: ubi: set ROOT_DEV to ubiblock "rootfs" if unset | ||||||
|  |  | ||||||
|  | Signed-off-by: Daniel Golle <daniel@makrotopia.org> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/ubi/block.c | 10 ++++++++++ | ||||||
|  |  1 file changed, 10 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/ubi/block.c | ||||||
|  | +++ b/drivers/mtd/ubi/block.c | ||||||
|  | @@ -42,6 +42,7 @@ | ||||||
|  |  #include <linux/scatterlist.h> | ||||||
|  |  #include <linux/idr.h> | ||||||
|  |  #include <asm/div64.h> | ||||||
|  | +#include <linux/root_dev.h> | ||||||
|  |   | ||||||
|  |  #include "ubi-media.h" | ||||||
|  |  #include "ubi.h" | ||||||
|  | @@ -458,6 +459,15 @@ int ubiblock_create(struct ubi_volume_in | ||||||
|  |  	dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)", | ||||||
|  |  		 dev->ubi_num, dev->vol_id, vi->name); | ||||||
|  |  	mutex_unlock(&devices_mutex); | ||||||
|  | + | ||||||
|  | +	if (!strcmp(vi->name, "rootfs") && | ||||||
|  | +	    IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) && | ||||||
|  | +	    ROOT_DEV == 0) { | ||||||
|  | +		pr_notice("ubiblock: device ubiblock%d_%d (%s) set to be root filesystem\n", | ||||||
|  | +			  dev->ubi_num, dev->vol_id, vi->name); | ||||||
|  | +		ROOT_DEV = MKDEV(gd->major, gd->first_minor); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	return 0; | ||||||
|  |   | ||||||
|  |  out_free_queue: | ||||||
| @@ -0,0 +1,60 @@ | |||||||
|  | From: Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | Subject: mtd: add EOF marker support to the UBI layer | ||||||
|  |  | ||||||
|  | Signed-off-by: Gabor Juhos <juhosg@openwrt.org> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/ubi/attach.c | 25 ++++++++++++++++++++++--- | ||||||
|  |  drivers/mtd/ubi/ubi.h    |  1 + | ||||||
|  |  2 files changed, 23 insertions(+), 3 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/ubi/attach.c | ||||||
|  | +++ b/drivers/mtd/ubi/attach.c | ||||||
|  | @@ -926,6 +926,13 @@ static bool vol_ignored(int vol_id) | ||||||
|  |  #endif | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +static bool ec_hdr_has_eof(struct ubi_ec_hdr *ech) | ||||||
|  | +{ | ||||||
|  | +	return ech->padding1[0] == 'E' && | ||||||
|  | +	       ech->padding1[1] == 'O' && | ||||||
|  | +	       ech->padding1[2] == 'F'; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  /** | ||||||
|  |   * scan_peb - scan and process UBI headers of a PEB. | ||||||
|  |   * @ubi: UBI device description object | ||||||
|  | @@ -958,9 +965,21 @@ static int scan_peb(struct ubi_device *u | ||||||
|  |  		return 0; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); | ||||||
|  | -	if (err < 0) | ||||||
|  | -		return err; | ||||||
|  | +	if (!ai->eof_found) { | ||||||
|  | +		err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0); | ||||||
|  | +		if (err < 0) | ||||||
|  | +			return err; | ||||||
|  | + | ||||||
|  | +		if (ec_hdr_has_eof(ech)) { | ||||||
|  | +			pr_notice("UBI: EOF marker found, PEBs from %d will be erased\n", | ||||||
|  | +				pnum); | ||||||
|  | +			ai->eof_found = true; | ||||||
|  | +		} | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	if (ai->eof_found) | ||||||
|  | +		err = UBI_IO_FF_BITFLIPS; | ||||||
|  | + | ||||||
|  |  	switch (err) { | ||||||
|  |  	case 0: | ||||||
|  |  		break; | ||||||
|  | --- a/drivers/mtd/ubi/ubi.h | ||||||
|  | +++ b/drivers/mtd/ubi/ubi.h | ||||||
|  | @@ -782,6 +782,7 @@ struct ubi_attach_info { | ||||||
|  |  	int mean_ec; | ||||||
|  |  	uint64_t ec_sum; | ||||||
|  |  	int ec_count; | ||||||
|  | +	bool eof_found; | ||||||
|  |  	struct kmem_cache *aeb_slab_cache; | ||||||
|  |  	struct ubi_ec_hdr *ech; | ||||||
|  |  	struct ubi_vid_io_buf *vidb; | ||||||
| @@ -0,0 +1,75 @@ | |||||||
|  | From 1bd1b740f208d1cf4071932cc51860d37266c402 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Bernhard Frauendienst <kernel@nospam.obeliks.de> | ||||||
|  | Date: Sat, 1 Sep 2018 00:30:11 +0200 | ||||||
|  | Subject: [PATCH 495/497] mtd: core: add get_mtd_device_by_node | ||||||
|  |  | ||||||
|  | Add function to retrieve a mtd device by its OF node. Since drivers can | ||||||
|  | assign arbitrary names to mtd devices in the absence of a label | ||||||
|  | property, there is no other reliable way to retrieve a mtd device for a | ||||||
|  | given OF node. | ||||||
|  |  | ||||||
|  | Signed-off-by: Bernhard Frauendienst <kernel@nospam.obeliks.de> | ||||||
|  | Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/mtdcore.c   | 38 ++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  include/linux/mtd/mtd.h |  2 ++ | ||||||
|  |  2 files changed, 40 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/mtdcore.c | ||||||
|  | +++ b/drivers/mtd/mtdcore.c | ||||||
|  | @@ -1052,6 +1052,44 @@ out_unlock: | ||||||
|  |  } | ||||||
|  |  EXPORT_SYMBOL_GPL(get_mtd_device_nm); | ||||||
|  |   | ||||||
|  | +/** | ||||||
|  | + *	get_mtd_device_by_node - obtain a validated handle for an MTD device | ||||||
|  | + *	by of_node | ||||||
|  | + *	@of_node: OF node of MTD device to open | ||||||
|  | + * | ||||||
|  | + *	This function returns MTD device description structure in case of | ||||||
|  | + *	success and an error code in case of failure. | ||||||
|  | + */ | ||||||
|  | +struct mtd_info *get_mtd_device_by_node(const struct device_node *of_node) | ||||||
|  | +{ | ||||||
|  | +	int err = -ENODEV; | ||||||
|  | +	struct mtd_info *mtd = NULL, *other; | ||||||
|  | + | ||||||
|  | +	mutex_lock(&mtd_table_mutex); | ||||||
|  | + | ||||||
|  | +	mtd_for_each_device(other) { | ||||||
|  | +		if (of_node == other->dev.of_node) { | ||||||
|  | +			mtd = other; | ||||||
|  | +			break; | ||||||
|  | +		} | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	if (!mtd) | ||||||
|  | +		goto out_unlock; | ||||||
|  | + | ||||||
|  | +	err = __get_mtd_device(mtd); | ||||||
|  | +	if (err) | ||||||
|  | +		goto out_unlock; | ||||||
|  | + | ||||||
|  | +	mutex_unlock(&mtd_table_mutex); | ||||||
|  | +	return mtd; | ||||||
|  | + | ||||||
|  | +out_unlock: | ||||||
|  | +	mutex_unlock(&mtd_table_mutex); | ||||||
|  | +	return ERR_PTR(err); | ||||||
|  | +} | ||||||
|  | +EXPORT_SYMBOL_GPL(get_mtd_device_by_node); | ||||||
|  | + | ||||||
|  |  void put_mtd_device(struct mtd_info *mtd) | ||||||
|  |  { | ||||||
|  |  	mutex_lock(&mtd_table_mutex); | ||||||
|  | --- a/include/linux/mtd/mtd.h | ||||||
|  | +++ b/include/linux/mtd/mtd.h | ||||||
|  | @@ -696,6 +696,8 @@ extern struct mtd_info *get_mtd_device(s | ||||||
|  |  extern int __get_mtd_device(struct mtd_info *mtd); | ||||||
|  |  extern void __put_mtd_device(struct mtd_info *mtd); | ||||||
|  |  extern struct mtd_info *get_mtd_device_nm(const char *name); | ||||||
|  | +extern struct mtd_info *get_mtd_device_by_node( | ||||||
|  | +		const struct device_node *of_node); | ||||||
|  |  extern void put_mtd_device(struct mtd_info *mtd); | ||||||
|  |   | ||||||
|  |  static inline uint64_t mtdpart_get_offset(const struct mtd_info *mtd) | ||||||
| @@ -0,0 +1,52 @@ | |||||||
|  | From 5734c6669fba7ddb5ef491ccff7159d15dba0b59 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Bernhard Frauendienst <kernel@nospam.obeliks.de> | ||||||
|  | Date: Wed, 5 Sep 2018 01:32:51 +0200 | ||||||
|  | Subject: [PATCH 496/497] dt-bindings: add bindings for mtd-concat devices | ||||||
|  |  | ||||||
|  | Document virtual mtd-concat device bindings. | ||||||
|  |  | ||||||
|  | Signed-off-by: Bernhard Frauendienst <kernel@nospam.obeliks.de> | ||||||
|  | --- | ||||||
|  |  .../devicetree/bindings/mtd/mtd-concat.txt    | 36 +++++++++++++++++++ | ||||||
|  |  1 file changed, 36 insertions(+) | ||||||
|  |  create mode 100644 Documentation/devicetree/bindings/mtd/mtd-concat.txt | ||||||
|  |  | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/Documentation/devicetree/bindings/mtd/mtd-concat.txt | ||||||
|  | @@ -0,0 +1,36 @@ | ||||||
|  | +Virtual MTD concat device | ||||||
|  | + | ||||||
|  | +Requires properties: | ||||||
|  | +- devices: list of phandles to mtd nodes that should be concatenated | ||||||
|  | + | ||||||
|  | +Example: | ||||||
|  | + | ||||||
|  | +&spi { | ||||||
|  | +	flash0: flash@0 { | ||||||
|  | +		... | ||||||
|  | +	}; | ||||||
|  | +	flash1: flash@1 { | ||||||
|  | +		... | ||||||
|  | +	}; | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +flash { | ||||||
|  | +	compatible = "mtd-concat"; | ||||||
|  | + | ||||||
|  | +	devices = <&flash0 &flash1>; | ||||||
|  | + | ||||||
|  | +	partitions { | ||||||
|  | +		compatible = "fixed-partitions"; | ||||||
|  | + | ||||||
|  | +		partition@0 { | ||||||
|  | +			label = "boot"; | ||||||
|  | +			reg = <0x0000000 0x0040000>; | ||||||
|  | +			read-only; | ||||||
|  | +		}; | ||||||
|  | + | ||||||
|  | +		partition@40000 { | ||||||
|  | +			label = "firmware"; | ||||||
|  | +			reg = <0x0040000 0x1fc0000>; | ||||||
|  | +		}; | ||||||
|  | +	} | ||||||
|  | +} | ||||||
| @@ -0,0 +1,216 @@ | |||||||
|  | From e53f712d8eac71f54399b61038ccf87d2cee99d7 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Bernhard Frauendienst <kernel@nospam.obeliks.de> | ||||||
|  | Date: Sat, 25 Aug 2018 12:35:22 +0200 | ||||||
|  | Subject: [PATCH 497/497] mtd: mtdconcat: add dt driver for concat devices | ||||||
|  |  | ||||||
|  | Some mtd drivers like physmap variants have support for concatenating | ||||||
|  | multiple mtd devices, but there is no generic way to define such a | ||||||
|  | concat device from within the device tree. | ||||||
|  |  | ||||||
|  | This is useful for some SoC boards that use multiple flash chips as | ||||||
|  | memory banks of a single mtd device, with partitions spanning chip | ||||||
|  | borders. | ||||||
|  |  | ||||||
|  | This commit adds a driver for creating virtual mtd-concat devices. They | ||||||
|  | must have a compatible = "mtd-concat" line, and define a list of devices | ||||||
|  | to concat in the 'devices' property, for example: | ||||||
|  |  | ||||||
|  | flash { | ||||||
|  |   compatible = "mtd-concat"; | ||||||
|  |  | ||||||
|  |   devices = <&flash0 &flash1>; | ||||||
|  |  | ||||||
|  |   partitions { | ||||||
|  |     ... | ||||||
|  |   }; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | The driver is added to the very end of the mtd Makefile to increase the | ||||||
|  | likelyhood of all child devices already being loaded at the time of | ||||||
|  | probing, preventing unnecessary deferred probes. | ||||||
|  |  | ||||||
|  | Signed-off-by: Bernhard Frauendienst <kernel@nospam.obeliks.de> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/Kconfig                 |   2 + | ||||||
|  |  drivers/mtd/Makefile                |   3 + | ||||||
|  |  drivers/mtd/composite/Kconfig       |  12 +++ | ||||||
|  |  drivers/mtd/composite/Makefile      |   6 ++ | ||||||
|  |  drivers/mtd/composite/virt_concat.c | 128 ++++++++++++++++++++++++++++ | ||||||
|  |  5 files changed, 151 insertions(+) | ||||||
|  |  create mode 100644 drivers/mtd/composite/Kconfig | ||||||
|  |  create mode 100644 drivers/mtd/composite/Makefile | ||||||
|  |  create mode 100644 drivers/mtd/composite/virt_concat.c | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/Kconfig | ||||||
|  | +++ b/drivers/mtd/Kconfig | ||||||
|  | @@ -238,4 +238,6 @@ source "drivers/mtd/ubi/Kconfig" | ||||||
|  |   | ||||||
|  |  source "drivers/mtd/hyperbus/Kconfig" | ||||||
|  |   | ||||||
|  | +source "drivers/mtd/composite/Kconfig" | ||||||
|  | + | ||||||
|  |  endif # MTD | ||||||
|  | --- a/drivers/mtd/Makefile | ||||||
|  | +++ b/drivers/mtd/Makefile | ||||||
|  | @@ -33,3 +33,6 @@ obj-y		+= chips/ lpddr/ maps/ devices/ n | ||||||
|  |  obj-$(CONFIG_MTD_SPI_NOR)	+= spi-nor/ | ||||||
|  |  obj-$(CONFIG_MTD_UBI)		+= ubi/ | ||||||
|  |  obj-$(CONFIG_MTD_HYPERBUS)	+= hyperbus/ | ||||||
|  | + | ||||||
|  | +# Composite drivers must be loaded last | ||||||
|  | +obj-y				+= composite/ | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/drivers/mtd/composite/Kconfig | ||||||
|  | @@ -0,0 +1,12 @@ | ||||||
|  | +menu "Composite MTD device drivers" | ||||||
|  | +	depends on MTD!=n | ||||||
|  | + | ||||||
|  | +config MTD_VIRT_CONCAT | ||||||
|  | +	tristate "Virtual concat MTD device" | ||||||
|  | +	help | ||||||
|  | +	  This driver allows creation of a virtual MTD concat device, which | ||||||
|  | +	  concatenates multiple underlying MTD devices to a single device. | ||||||
|  | +	  This is required by some SoC boards where multiple memory banks are | ||||||
|  | +	  used as one device with partitions spanning across device boundaries. | ||||||
|  | + | ||||||
|  | +endmenu | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/drivers/mtd/composite/Makefile | ||||||
|  | @@ -0,0 +1,6 @@ | ||||||
|  | +# SPDX-License-Identifier: GPL-2.0 | ||||||
|  | +# | ||||||
|  | +# linux/drivers/mtd/composite/Makefile | ||||||
|  | +# | ||||||
|  | + | ||||||
|  | +obj-$(CONFIG_MTD_VIRT_CONCAT)   += virt_concat.o | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/drivers/mtd/composite/virt_concat.c | ||||||
|  | @@ -0,0 +1,128 @@ | ||||||
|  | +// SPDX-License-Identifier: GPL-2.0+ | ||||||
|  | +/* | ||||||
|  | + * Virtual concat MTD device driver | ||||||
|  | + * | ||||||
|  | + * Copyright (C) 2018 Bernhard Frauendienst | ||||||
|  | + * Author: Bernhard Frauendienst, kernel@nospam.obeliks.de | ||||||
|  | + */ | ||||||
|  | + | ||||||
|  | +#include <linux/module.h> | ||||||
|  | +#include <linux/device.h> | ||||||
|  | +#include <linux/mtd/concat.h> | ||||||
|  | +#include <linux/mtd/mtd.h> | ||||||
|  | +#include <linux/mtd/partitions.h> | ||||||
|  | +#include <linux/of.h> | ||||||
|  | +#include <linux/of_platform.h> | ||||||
|  | +#include <linux/slab.h> | ||||||
|  | + | ||||||
|  | +/* | ||||||
|  | + * struct of_virt_concat - platform device driver data. | ||||||
|  | + * @cmtd the final mtd_concat device | ||||||
|  | + * @num_devices the number of devices in @devices | ||||||
|  | + * @devices points to an array of devices already loaded | ||||||
|  | + */ | ||||||
|  | +struct of_virt_concat { | ||||||
|  | +	struct mtd_info	*cmtd; | ||||||
|  | +	int num_devices; | ||||||
|  | +	struct mtd_info	**devices; | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +static int virt_concat_remove(struct platform_device *pdev) | ||||||
|  | +{ | ||||||
|  | +	struct of_virt_concat *info; | ||||||
|  | +	int i; | ||||||
|  | + | ||||||
|  | +	info = platform_get_drvdata(pdev); | ||||||
|  | +	if (!info) | ||||||
|  | +		return 0; | ||||||
|  | + | ||||||
|  | +	// unset data for when this is called after a probe error | ||||||
|  | +	platform_set_drvdata(pdev, NULL); | ||||||
|  | + | ||||||
|  | +	if (info->cmtd) { | ||||||
|  | +		mtd_device_unregister(info->cmtd); | ||||||
|  | +		mtd_concat_destroy(info->cmtd); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	if (info->devices) { | ||||||
|  | +		for (i = 0; i < info->num_devices; i++) | ||||||
|  | +			put_mtd_device(info->devices[i]); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static int virt_concat_probe(struct platform_device *pdev) | ||||||
|  | +{ | ||||||
|  | +	struct device_node *node = pdev->dev.of_node; | ||||||
|  | +	struct of_phandle_iterator it; | ||||||
|  | +	struct of_virt_concat *info; | ||||||
|  | +	struct mtd_info *mtd; | ||||||
|  | +	int err = 0, count; | ||||||
|  | + | ||||||
|  | +	count = of_count_phandle_with_args(node, "devices", NULL); | ||||||
|  | +	if (count <= 0) | ||||||
|  | +		return -EINVAL; | ||||||
|  | + | ||||||
|  | +	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); | ||||||
|  | +	if (!info) | ||||||
|  | +		return -ENOMEM; | ||||||
|  | +	info->devices = devm_kcalloc(&pdev->dev, count, | ||||||
|  | +				     sizeof(*(info->devices)), GFP_KERNEL); | ||||||
|  | +	if (!info->devices) { | ||||||
|  | +		err = -ENOMEM; | ||||||
|  | +		goto err_remove; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	platform_set_drvdata(pdev, info); | ||||||
|  | + | ||||||
|  | +	of_for_each_phandle(&it, err, node, "devices", NULL, 0) { | ||||||
|  | +		mtd = get_mtd_device_by_node(it.node); | ||||||
|  | +		if (IS_ERR(mtd)) { | ||||||
|  | +			of_node_put(it.node); | ||||||
|  | +			err = -EPROBE_DEFER; | ||||||
|  | +			goto err_remove; | ||||||
|  | +		} | ||||||
|  | + | ||||||
|  | +		info->devices[info->num_devices++] = mtd; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	info->cmtd = mtd_concat_create(info->devices, info->num_devices, | ||||||
|  | +				       dev_name(&pdev->dev)); | ||||||
|  | +	if (!info->cmtd) { | ||||||
|  | +		err = -ENXIO; | ||||||
|  | +		goto err_remove; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	info->cmtd->dev.parent = &pdev->dev; | ||||||
|  | +	mtd_set_of_node(info->cmtd, node); | ||||||
|  | +	mtd_device_register(info->cmtd, NULL, 0); | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | + | ||||||
|  | +err_remove: | ||||||
|  | +	virt_concat_remove(pdev); | ||||||
|  | + | ||||||
|  | +	return err; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static const struct of_device_id virt_concat_of_match[] = { | ||||||
|  | +	{ .compatible = "mtd-concat", }, | ||||||
|  | +	{ /* sentinel */ } | ||||||
|  | +}; | ||||||
|  | +MODULE_DEVICE_TABLE(of, virt_concat_of_match); | ||||||
|  | + | ||||||
|  | +static struct platform_driver virt_concat_driver = { | ||||||
|  | +	.probe = virt_concat_probe, | ||||||
|  | +	.remove = virt_concat_remove, | ||||||
|  | +	.driver	 = { | ||||||
|  | +		.name   = "virt-mtdconcat", | ||||||
|  | +		.of_match_table = virt_concat_of_match, | ||||||
|  | +	}, | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +module_platform_driver(virt_concat_driver); | ||||||
|  | + | ||||||
|  | +MODULE_LICENSE("GPL v2"); | ||||||
|  | +MODULE_AUTHOR("Bernhard Frauendienst <kernel@nospam.obeliks.de>"); | ||||||
|  | +MODULE_DESCRIPTION("Virtual concat MTD device driver"); | ||||||
| @@ -0,0 +1,24 @@ | |||||||
|  | --- a/drivers/mtd/mtdconcat.c | ||||||
|  | +++ b/drivers/mtd/mtdconcat.c | ||||||
|  | @@ -683,8 +683,12 @@ struct mtd_info *mtd_concat_create(struc | ||||||
|  |  		concat->mtd._writev = concat_writev; | ||||||
|  |  	if (subdev[0]->_read_oob) | ||||||
|  |  		concat->mtd._read_oob = concat_read_oob; | ||||||
|  | +	else | ||||||
|  | +		concat->mtd._read = concat_read; | ||||||
|  |  	if (subdev[0]->_write_oob) | ||||||
|  |  		concat->mtd._write_oob = concat_write_oob; | ||||||
|  | +	else | ||||||
|  | +		concat->mtd._write = concat_write; | ||||||
|  |  	if (subdev[0]->_block_isbad) | ||||||
|  |  		concat->mtd._block_isbad = concat_block_isbad; | ||||||
|  |  	if (subdev[0]->_block_markbad) | ||||||
|  | @@ -744,8 +748,6 @@ struct mtd_info *mtd_concat_create(struc | ||||||
|  |  	concat->mtd.name = name; | ||||||
|  |   | ||||||
|  |  	concat->mtd._erase = concat_erase; | ||||||
|  | -	concat->mtd._read = concat_read; | ||||||
|  | -	concat->mtd._write = concat_write; | ||||||
|  |  	concat->mtd._sync = concat_sync; | ||||||
|  |  	concat->mtd._lock = concat_lock; | ||||||
|  |  	concat->mtd._unlock = concat_unlock; | ||||||
| @@ -0,0 +1,40 @@ | |||||||
|  | --- a/fs/hfs/Kconfig | ||||||
|  | +++ b/fs/hfs/Kconfig | ||||||
|  | @@ -2,6 +2,7 @@ | ||||||
|  |  config HFS_FS | ||||||
|  |  	tristate "Apple Macintosh file system support" | ||||||
|  |  	depends on BLOCK | ||||||
|  | +	select CDROM | ||||||
|  |  	select NLS | ||||||
|  |  	help | ||||||
|  |  	  If you say Y here, you will be able to mount Macintosh-formatted | ||||||
|  | --- a/fs/hfsplus/Kconfig | ||||||
|  | +++ b/fs/hfsplus/Kconfig | ||||||
|  | @@ -2,6 +2,7 @@ | ||||||
|  |  config HFSPLUS_FS | ||||||
|  |  	tristate "Apple Extended HFS file system support" | ||||||
|  |  	depends on BLOCK | ||||||
|  | +	select CDROM | ||||||
|  |  	select NLS | ||||||
|  |  	select NLS_UTF8 | ||||||
|  |  	help | ||||||
|  | --- a/fs/isofs/Kconfig | ||||||
|  | +++ b/fs/isofs/Kconfig | ||||||
|  | @@ -1,6 +1,7 @@ | ||||||
|  |  # SPDX-License-Identifier: GPL-2.0-only | ||||||
|  |  config ISO9660_FS | ||||||
|  |  	tristate "ISO 9660 CDROM file system support" | ||||||
|  | +	select CDROM | ||||||
|  |  	help | ||||||
|  |  	  This is the standard file system used on CD-ROMs.  It was previously | ||||||
|  |  	  known as "High Sierra File System" and is called "hsfs" on other | ||||||
|  | --- a/fs/udf/Kconfig | ||||||
|  | +++ b/fs/udf/Kconfig | ||||||
|  | @@ -1,6 +1,7 @@ | ||||||
|  |  # SPDX-License-Identifier: GPL-2.0-only | ||||||
|  |  config UDF_FS | ||||||
|  |  	tristate "UDF file system support" | ||||||
|  | +	select CDROM | ||||||
|  |  	select CRC_ITU_T | ||||||
|  |  	select NLS | ||||||
|  |  	help | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										65
									
								
								target/linux/generic/pending-5.10/532-jffs2_eofdetect.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								target/linux/generic/pending-5.10/532-jffs2_eofdetect.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | |||||||
|  | From: Felix Fietkau <nbd@nbd.name> | ||||||
|  | Subject: fs: jffs2: EOF marker | ||||||
|  |  | ||||||
|  | Signed-off-by: Felix Fietkau <nbd@nbd.name> | ||||||
|  | --- | ||||||
|  |  fs/jffs2/build.c | 10 ++++++++++ | ||||||
|  |  fs/jffs2/scan.c  | 21 +++++++++++++++++++-- | ||||||
|  |  2 files changed, 29 insertions(+), 2 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/fs/jffs2/build.c | ||||||
|  | +++ b/fs/jffs2/build.c | ||||||
|  | @@ -117,6 +117,16 @@ static int jffs2_build_filesystem(struct | ||||||
|  |  	dbg_fsbuild("scanned flash completely\n"); | ||||||
|  |  	jffs2_dbg_dump_block_lists_nolock(c); | ||||||
|  |   | ||||||
|  | +	if (c->flags & (1 << 7)) { | ||||||
|  | +		printk("%s(): unlocking the mtd device... ", __func__); | ||||||
|  | +		mtd_unlock(c->mtd, 0, c->mtd->size); | ||||||
|  | +		printk("done.\n"); | ||||||
|  | + | ||||||
|  | +		printk("%s(): erasing all blocks after the end marker... ", __func__); | ||||||
|  | +		jffs2_erase_pending_blocks(c, -1); | ||||||
|  | +		printk("done.\n"); | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	dbg_fsbuild("pass 1 starting\n"); | ||||||
|  |  	c->flags |= JFFS2_SB_FLAG_BUILDING; | ||||||
|  |  	/* Now scan the directory tree, increasing nlink according to every dirent found. */ | ||||||
|  | --- a/fs/jffs2/scan.c | ||||||
|  | +++ b/fs/jffs2/scan.c | ||||||
|  | @@ -148,8 +148,14 @@ int jffs2_scan_medium(struct jffs2_sb_in | ||||||
|  |  		/* reset summary info for next eraseblock scan */ | ||||||
|  |  		jffs2_sum_reset_collected(s); | ||||||
|  |   | ||||||
|  | -		ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), | ||||||
|  | -						buf_size, s); | ||||||
|  | +		if (c->flags & (1 << 7)) { | ||||||
|  | +			if (mtd_block_isbad(c->mtd, jeb->offset)) | ||||||
|  | +				ret = BLK_STATE_BADBLOCK; | ||||||
|  | +			else | ||||||
|  | +				ret = BLK_STATE_ALLFF; | ||||||
|  | +		} else | ||||||
|  | +			ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), | ||||||
|  | +							buf_size, s); | ||||||
|  |   | ||||||
|  |  		if (ret < 0) | ||||||
|  |  			goto out; | ||||||
|  | @@ -565,6 +571,17 @@ full_scan: | ||||||
|  |  			return err; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	if ((buf[0] == 0xde) && | ||||||
|  | +		(buf[1] == 0xad) && | ||||||
|  | +		(buf[2] == 0xc0) && | ||||||
|  | +		(buf[3] == 0xde)) { | ||||||
|  | +		/* end of filesystem. erase everything after this point */ | ||||||
|  | +		printk("%s(): End of filesystem marker found at 0x%x\n", __func__, jeb->offset); | ||||||
|  | +		c->flags |= (1 << 7); | ||||||
|  | + | ||||||
|  | +		return BLK_STATE_ALLFF; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  |  	/* We temporarily use 'ofs' as a pointer into the buffer/jeb */ | ||||||
|  |  	ofs = 0; | ||||||
|  |  	max_ofs = EMPTY_SCAN_SIZE(c->sector_size); | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	 Felix Fietkau
					Felix Fietkau