summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBertrand Jacquin <bertrand@jacquin.bzh>2018-08-01 23:02:29 +0200
committerBertrand Jacquin <bertrand@jacquin.bzh>2018-08-01 23:03:46 +0200
commit761799ebbc378d6b4e3edb7037030d5ec0441d21 (patch)
treeb15abc94d0efa3561438942f2ed82166edae4a11
parentsys-kernel/longterm-sources: Update from v4.9.112 to v4.9.116 (diff)
downloadetc-portage-patches-761799ebbc378d6b4e3edb7037030d5ec0441d21.tar.gz
sys-kernel/stable-sources: Drop v4.16.18
-rw-r--r--sys-kernel/boest-v4.16.18/0001-patch-4.16-ja1.diff.patch2113
-rw-r--r--sys-kernel/boest-v4.16.18/0002-pool-2.6.25-tcp-timewait-20s.diff.patch27
-rw-r--r--sys-kernel/boest-v4.16.18/0003-pool-2.6.25-disable-tcp-debug.diff.patch25
-rw-r--r--sys-kernel/boest-v4.16.18/0004-pool-2.6.25-disable-kbdrate-at-boot.diff.patch34
-rw-r--r--sys-kernel/boest-v4.16.18/0005-x86-pci-add-support-for-pci-rev-net.patch75
-rw-r--r--sys-kernel/boest-v4.16.18/0006-Disable-CONFIG_PROCESSOR_SELECT-printk-s.patch45
-rw-r--r--sys-kernel/boest-v4.16.18/0007-This-patch-adds-support-for-a-restricted-user-contro.patch75
-rw-r--r--sys-kernel/boest-v4.16.18/0008-fs-Enable-link-security-restrictions-by-default.patch26
-rw-r--r--sys-kernel/boest-v4.16.18/0009-UBUNTU-SAUCE-PCI-Workaround-to-enable-poweroff-on-Ma.patch74
-rw-r--r--sys-kernel/boest-v4.16.18/0010-usb-storage-Disable-UAS-on-JMicron-SATA-enclosure.patch37
-rw-r--r--sys-kernel/boest-v4.16.18/0011-4.16-2600_enable-key-swapping-for-apple-mac.patch.patch125
-rw-r--r--sys-kernel/boest-v4.16.18/0012-4.16-2900_dev-root-proc-mount-fix.patch.patch49
-rw-r--r--sys-kernel/boest-v4.16.18/0013-4.16-4200_fbcondecor.patch.patch2119
-rw-r--r--sys-kernel/boest-v4.16.18/0014-4.16-4400_alpha-sysctl-uac.patch.patch153
-rw-r--r--sys-kernel/boest-v4.16.18/0015-4.16-4567_distro-Gentoo-Kconfig.patch.patch172
-rw-r--r--sys-kernel/boest-v4.16.18/0016-WARNING.patch550
l---------sys-kernel/stable-sources-4.16.181
17 files changed, 0 insertions, 5700 deletions
diff --git a/sys-kernel/boest-v4.16.18/0001-patch-4.16-ja1.diff.patch b/sys-kernel/boest-v4.16.18/0001-patch-4.16-ja1.diff.patch
deleted file mode 100644
index 7fbd977d..00000000
--- a/sys-kernel/boest-v4.16.18/0001-patch-4.16-ja1.diff.patch
+++ /dev/null
@@ -1,2113 +0,0 @@
-From dc791003b5690f3c9c396ac4d7472bea9d7c3857 Mon Sep 17 00:00:00 2001
-From: Julian Anastasov <ja@ssi.bg>
-Date: Fri, 6 Apr 2018 11:51:41 +0000
-Subject: [PATCH 01/16] patch-4.16-ja1.diff
-
-Jumbo patch containing the following parts:
- - routes-2.X.*.diff (static_routes, alt_routes, nf_reroute but without arp_prefsrc functionality, it is replaced by arprules and rp_filter_mask)
- - hidden-2.X.*.diff (conf/*/hidden)
- - arprules-2.X.*.diff (iparp/arprules support)
- - rp_filter_mask-2.X.*.diff (conf/*/rp_filter_mask)
- - forward_shared-2.X.*.diff (conf/*/forward_shared)
- - send-to-self-2.X.*.diff (conf/*/loop, included March 3, 2004, up to Linux 3.5)
-
-URL: http://ja.ssi.bg/patch-4.16-ja1.diff
----
- Documentation/networking/ip-sysctl.txt | 30 ++
- include/linux/inetdevice.h | 3 +
- include/net/flow.h | 2 +
- include/net/ip_fib.h | 7 +-
- include/net/netfilter/nf_nat.h | 5 +
- include/net/route.h | 5 +
- include/uapi/linux/ip.h | 3 +
- include/uapi/linux/rtnetlink.h | 64 ++-
- net/bridge/br_netfilter_hooks.c | 3 +
- net/ipv4/arp.c | 695 +++++++++++++++++++++++++++-
- net/ipv4/devinet.c | 14 +-
- net/ipv4/fib_frontend.c | 56 ++-
- net/ipv4/fib_rules.c | 5 +
- net/ipv4/fib_semantics.c | 254 +++++++---
- net/ipv4/fib_trie.c | 3 +
- net/ipv4/netfilter/iptable_nat.c | 7 +
- net/ipv4/netfilter/nf_nat_masquerade_ipv4.c | 27 +-
- net/ipv4/route.c | 69 ++-
- net/netfilter/nf_nat_core.c | 43 ++
- security/selinux/nlmsgtab.c | 5 +-
- 20 files changed, 1175 insertions(+), 125 deletions(-)
-
-diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
-index f778901c4297..5568deeba662 100644
---- a/Documentation/networking/ip-sysctl.txt
-+++ b/Documentation/networking/ip-sysctl.txt
-@@ -1028,6 +1028,19 @@ forwarding - BOOLEAN
- Enable IP forwarding on this interface. This controls whether packets
- received _on_ this interface can be forwarded.
-
-+forward_shared - BOOLEAN
-+ Integer value determines if a source validation should allow
-+ forwarding of packets with local source address. 1 means yes,
-+ 0 means no. By default the flag is disabled and such packets
-+ are not forwarded.
-+
-+ If you enable this flag on internal network, the router will forward
-+ packets from internal hosts with shared IP addresses no matter how
-+ the rp_filter is set. This flag is activated only if it is
-+ enabled both in specific device section and in "all" section.
-+
-+ The forward_shared value could be ignored when rp_filter is set to 0.
-+
- mc_forwarding - BOOLEAN
- Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE
- and a multicast routing daemon is required.
-@@ -1143,6 +1156,15 @@ rp_filter - INTEGER
- Default value is 0. Note that some distributions enable it
- in startup scripts.
-
-+rp_filter_mask - INTEGER
-+ Integer value representing bitmask of the mediums for which the
-+ reverse path protection is disabled. If the source validation
-+ results in reverse path to interface with medium_id value in
-+ the 1..31 range the access is allowed if the corresponding bit
-+ is set in the bitmask. The bitmask value is considered only when
-+ rp_filter is enabled. By default the bitmask is empty preserving
-+ the original rp_filter semantic.
-+
- arp_filter - BOOLEAN
- 1 - Allows you to have multiple network interfaces on the same
- subnet, and have the ARPs for each interface be answered
-@@ -1283,6 +1305,14 @@ drop_gratuitous_arp - BOOLEAN
- Default: off (0)
-
-
-+hidden - BOOLEAN
-+ Hide addresses attached to this device from other devices.
-+ Such addresses will never be selected by source address autoselection
-+ mechanism, host does not answer broadcast ARP requests for them,
-+ does not announce them as source address of ARP requests, but they
-+ are still reachable via IP. This flag is activated only if it is
-+ enabled both in specific device section and in "all" section.
-+
- tag - INTEGER
- Allows you to write a number, which can be used as required.
- Default value is 0.
-diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
-index e16fe7d44a71..68be9fe9cad8 100644
---- a/include/linux/inetdevice.h
-+++ b/include/linux/inetdevice.h
-@@ -94,9 +94,11 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev)
- #define IN_DEV_FORWARD(in_dev) IN_DEV_CONF_GET((in_dev), FORWARDING)
- #define IN_DEV_MFORWARD(in_dev) IN_DEV_ANDCONF((in_dev), MC_FORWARDING)
- #define IN_DEV_RPFILTER(in_dev) IN_DEV_MAXCONF((in_dev), RP_FILTER)
-+#define IN_DEV_RPFILTER_MASK(in_dev) IN_DEV_CONF_GET(in_dev, RP_FILTER_MASK)
- #define IN_DEV_SRC_VMARK(in_dev) IN_DEV_ORCONF((in_dev), SRC_VMARK)
- #define IN_DEV_SOURCE_ROUTE(in_dev) IN_DEV_ANDCONF((in_dev), \
- ACCEPT_SOURCE_ROUTE)
-+#define IN_DEV_FORWARD_SHARED(in_dev) IN_DEV_ANDCONF((in_dev), FORWARD_SHARED)
- #define IN_DEV_ACCEPT_LOCAL(in_dev) IN_DEV_ORCONF((in_dev), ACCEPT_LOCAL)
- #define IN_DEV_BOOTP_RELAY(in_dev) IN_DEV_ANDCONF((in_dev), BOOTP_RELAY)
-
-@@ -109,6 +111,7 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev)
- SECURE_REDIRECTS)
- #define IN_DEV_IDTAG(in_dev) IN_DEV_CONF_GET(in_dev, TAG)
- #define IN_DEV_MEDIUM_ID(in_dev) IN_DEV_CONF_GET(in_dev, MEDIUM_ID)
-+#define IN_DEV_HIDDEN(in_dev) IN_DEV_ANDCONF((in_dev), HIDDEN)
- #define IN_DEV_PROMOTE_SECONDARIES(in_dev) \
- IN_DEV_ORCONF((in_dev), \
- PROMOTE_SECONDARIES)
-diff --git a/include/net/flow.h b/include/net/flow.h
-index f1624fd5b1d0..8f3a4068de18 100644
---- a/include/net/flow.h
-+++ b/include/net/flow.h
-@@ -91,6 +91,7 @@ struct flowi4 {
- #define fl4_ipsec_spi uli.spi
- #define fl4_mh_type uli.mht.type
- #define fl4_gre_key uli.gre_key
-+ __be32 fl4_gw;
- } __attribute__((__aligned__(BITS_PER_LONG/8)));
-
- static inline void flowi4_init_output(struct flowi4 *fl4, int oif,
-@@ -114,6 +115,7 @@ static inline void flowi4_init_output(struct flowi4 *fl4, int oif,
- fl4->saddr = saddr;
- fl4->fl4_dport = dport;
- fl4->fl4_sport = sport;
-+ fl4->fl4_gw = 0;
- }
-
- /* Reset some input parameters after previous lookup */
-diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
-index 77d0a78cf7d2..311a95ef78ad 100644
---- a/include/net/ip_fib.h
-+++ b/include/net/ip_fib.h
-@@ -342,6 +342,8 @@ bool fib4_rule_default(const struct fib_rule *rule);
- int fib4_rules_dump(struct net *net, struct notifier_block *nb);
- unsigned int fib4_rules_seq_read(struct net *net);
-
-+u32 fib_result_table(struct fib_result *res);
-+
- #endif /* CONFIG_IP_MULTIPLE_TABLES */
-
- /* Exported by fib_frontend.c */
-@@ -350,7 +352,8 @@ void ip_fib_init(void);
- __be32 fib_compute_spec_dst(struct sk_buff *skb);
- int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
- u8 tos, int oif, struct net_device *dev,
-- struct in_device *idev, u32 *itag);
-+ struct in_device *idev, u32 *itag, int our);
-+void fib_select_default(const struct flowi4 *flp, struct fib_result *res);
- #ifdef CONFIG_IP_ROUTE_CLASSID
- static inline int fib_num_tclassid_users(struct net *net)
- {
-@@ -424,4 +427,6 @@ static inline void fib_proc_exit(struct net *net)
- }
- #endif
-
-+extern rwlock_t fib_nhflags_lock;
-+
- #endif /* _NET_FIB_H */
-diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h
-index 207a467e7ca6..36d4aab0d98e 100644
---- a/include/net/netfilter/nf_nat.h
-+++ b/include/net/netfilter/nf_nat.h
-@@ -37,6 +37,11 @@ struct nf_conn_nat {
- #endif
- };
-
-+/* Call input routing for SNAT-ed traffic */
-+unsigned int ip_nat_route_input(void *priv,
-+ struct sk_buff *skb,
-+ const struct nf_hook_state *state);
-+
- /* Set up the info structure to map into this range. */
- unsigned int nf_nat_setup_info(struct nf_conn *ct,
- const struct nf_nat_range *range,
-diff --git a/include/net/route.h b/include/net/route.h
-index 20a92ca9e115..5a38cd44db51 100644
---- a/include/net/route.h
-+++ b/include/net/route.h
-@@ -184,6 +184,9 @@ int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 src,
- int ip_route_input_rcu(struct sk_buff *skb, __be32 dst, __be32 src,
- u8 tos, struct net_device *devin,
- struct fib_result *res);
-+int ip_route_input_common_rcu(struct sk_buff *skb, __be32 dst, __be32 src,
-+ u8 tos, struct net_device *devin, __be32 lsrc,
-+ struct fib_result *res);
-
- static inline int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src,
- u8 tos, struct net_device *devin)
-@@ -220,6 +223,8 @@ unsigned int inet_addr_type_dev_table(struct net *net,
- void ip_rt_multicast_event(struct in_device *);
- int ip_rt_ioctl(struct net *, unsigned int cmd, struct rtentry *rt);
- void ip_rt_get_source(u8 *src, struct sk_buff *skb, struct rtable *rt);
-+int ip_route_input_lookup(struct sk_buff*, __be32 dst, __be32 src, u8 tos,
-+ struct net_device *devin, __be32 lsrc);
- struct rtable *rt_dst_alloc(struct net_device *dev,
- unsigned int flags, u16 type,
- bool nopolicy, bool noxfrm, bool will_cache);
-diff --git a/include/uapi/linux/ip.h b/include/uapi/linux/ip.h
-index b24a742beae5..b94a1b50c83b 100644
---- a/include/uapi/linux/ip.h
-+++ b/include/uapi/linux/ip.h
-@@ -168,6 +168,9 @@ enum
- IPV4_DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN,
- IPV4_DEVCONF_DROP_UNICAST_IN_L2_MULTICAST,
- IPV4_DEVCONF_DROP_GRATUITOUS_ARP,
-+ IPV4_DEVCONF_HIDDEN,
-+ IPV4_DEVCONF_RP_FILTER_MASK,
-+ IPV4_DEVCONF_FORWARD_SHARED,
- __IPV4_DEVCONF_MAX
- };
-
-diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
-index 9b15005955fa..f69c9adaa499 100644
---- a/include/uapi/linux/rtnetlink.h
-+++ b/include/uapi/linux/rtnetlink.h
-@@ -150,6 +150,13 @@ enum {
- RTM_NEWCACHEREPORT = 96,
- #define RTM_NEWCACHEREPORT RTM_NEWCACHEREPORT
-
-+ RTM_NEWARPRULE = 100,
-+#define RTM_NEWARPRULE RTM_NEWARPRULE
-+ RTM_DELARPRULE,
-+#define RTM_DELARPRULE RTM_DELARPRULE
-+ RTM_GETARPRULE,
-+#define RTM_GETARPRULE RTM_GETARPRULE
-+
- __RTM_MAX,
- #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
- };
-@@ -359,8 +366,11 @@ struct rtnexthop {
- #define RTNH_F_OFFLOAD 8 /* offloaded route */
- #define RTNH_F_LINKDOWN 16 /* carrier-down on nexthop */
- #define RTNH_F_UNRESOLVED 32 /* The entry is unresolved (ipmr) */
-+#define RTNH_F_SUSPECT 64 /* We don't know the real state */
-+#define RTNH_F_BADSTATE (RTNH_F_DEAD | RTNH_F_SUSPECT)
-
--#define RTNH_COMPARE_MASK (RTNH_F_DEAD | RTNH_F_LINKDOWN | RTNH_F_OFFLOAD)
-+#define RTNH_COMPARE_MASK (RTNH_F_DEAD | RTNH_F_LINKDOWN | \
-+ RTNH_F_OFFLOAD | RTNH_F_SUSPECT)
-
- /* Macros to handle hexthops */
-
-@@ -602,6 +612,54 @@ enum {
-
- #define NDUSEROPT_MAX (__NDUSEROPT_MAX - 1)
-
-+/******************************************************************************
-+ * Definitions used in ARP tables administration
-+ ****/
-+
-+#define ARPA_TABLE_INPUT 0
-+#define ARPA_TABLE_OUTPUT 1
-+#define ARPA_TABLE_FORWARD 2
-+#define ARPA_TABLE_ALL -1
-+
-+#define ARPM_F_PREFSRC 0x0001
-+#define ARPM_F_WILDIIF 0x0002
-+#define ARPM_F_WILDOIF 0x0004
-+#define ARPM_F_BROADCAST 0x0008
-+#define ARPM_F_UNICAST 0x0010
-+
-+struct arpmsg
-+{
-+ unsigned char arpm_family;
-+ unsigned char arpm_table;
-+ unsigned char arpm_action;
-+ unsigned char arpm_from_len;
-+ unsigned char arpm_to_len;
-+ unsigned char arpm__pad1;
-+ unsigned short arpm__pad2;
-+ unsigned arpm_pref;
-+ unsigned arpm_flags;
-+};
-+
-+enum
-+{
-+ ARPA_UNSPEC,
-+ ARPA_FROM, /* FROM IP prefix */
-+ ARPA_TO, /* TO IP prefix */
-+ ARPA_LLFROM, /* FROM LL prefix */
-+ ARPA_LLTO, /* TO LL prefix */
-+ ARPA_LLSRC, /* New SRC lladdr */
-+ ARPA_LLDST, /* New DST lladdr */
-+ ARPA_IIF, /* In interface prefix */
-+ ARPA_OIF, /* Out interface prefix */
-+ ARPA_SRC, /* New IP SRC */
-+ ARPA_DST, /* New IP DST, not used */
-+ ARPA_PACKETS, /* Packets */
-+};
-+
-+#define ARPA_MAX ARPA_PACKETS
-+
-+#define ARPA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct arpmsg))))
-+
- #ifndef __KERNEL__
- /* RTnetlink multicast groups - backwards compatibility for userspace */
- #define RTMGRP_LINK 1
-@@ -622,6 +680,8 @@ enum {
- #define RTMGRP_DECnet_IFADDR 0x1000
- #define RTMGRP_DECnet_ROUTE 0x4000
-
-+#define RTMGRP_ARP 0x00010000
-+
- #define RTMGRP_IPV6_PREFIX 0x20000
- #endif
-
-@@ -689,6 +749,8 @@ enum rtnetlink_groups {
- #define RTNLGRP_IPV4_MROUTE_R RTNLGRP_IPV4_MROUTE_R
- RTNLGRP_IPV6_MROUTE_R,
- #define RTNLGRP_IPV6_MROUTE_R RTNLGRP_IPV6_MROUTE_R
-+ RTNLGRP_ARP,
-+#define RTNLGRP_ARP RTNLGRP_ARP
- __RTNLGRP_MAX
- };
- #define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
-diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
-index 9b16eaf33819..d6647e8ff627 100644
---- a/net/bridge/br_netfilter_hooks.c
-+++ b/net/bridge/br_netfilter_hooks.c
-@@ -359,6 +359,9 @@ static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_
-
- nf_bridge->frag_max_size = IPCB(skb)->frag_max_size;
-
-+ /* Old skb->dst is not expected, it is lost in all cases */
-+ skb_dst_drop(skb);
-+
- if (nf_bridge->pkt_otherhost) {
- skb->pkt_type = PACKET_OTHERHOST;
- nf_bridge->pkt_otherhost = false;
-diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
-index 7333db17c581..2e0d304de732 100644
---- a/net/ipv4/arp.c
-+++ b/net/ipv4/arp.c
-@@ -71,6 +71,9 @@
- * sending (e.g. insert 8021q tag).
- * Harald Welte : convert to make use of jenkins hash
- * Jesper D. Brouer: Proxy ARP PVLAN RFC 3069 support.
-+ * Julian Anastasov: "hidden" flag: hide the
-+ * interface and don't reply for it
-+ * Julian Anastasov: ARP filtering via netlink
- */
-
- #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-@@ -95,6 +98,7 @@
- #include <linux/proc_fs.h>
- #include <linux/seq_file.h>
- #include <linux/stat.h>
-+#include <net/netlink.h>
- #include <linux/init.h>
- #include <linux/net.h>
- #include <linux/rcupdate.h>
-@@ -185,6 +189,48 @@ struct neigh_table arp_tbl = {
- };
- EXPORT_SYMBOL(arp_tbl);
-
-+struct arpf_node {
-+ struct arpf_node * at_next;
-+ u32 at_pref;
-+ u32 at_from;
-+ u32 at_from_mask;
-+ u32 at_to;
-+ u32 at_to_mask;
-+ u32 at_src;
-+ atomic_t at_packets;
-+ atomic_t at_refcnt;
-+ unsigned at_flags;
-+ unsigned char at_from_len;
-+ unsigned char at_to_len;
-+ unsigned char at_action;
-+ char at_dead;
-+ unsigned char at_llfrom_len;
-+ unsigned char at_llto_len;
-+ unsigned char at_llsrc_len;
-+ unsigned char at_lldst_len;
-+ unsigned char at_iif_len;
-+ unsigned char at_oif_len;
-+ unsigned short at__pad1;
-+ unsigned char at_llfrom[MAX_ADDR_LEN];
-+ unsigned char at_llto[MAX_ADDR_LEN];
-+ unsigned char at_llsrc[MAX_ADDR_LEN];
-+ unsigned char at_lldst[MAX_ADDR_LEN];
-+ char at_iif[IFNAMSIZ];
-+ char at_oif[IFNAMSIZ];
-+};
-+
-+static struct arpf_node *arp_tabs[3];
-+
-+static struct kmem_cache *arpf_cachep;
-+
-+static DEFINE_RWLOCK(arpf_lock);
-+
-+static void
-+arpf_send(int table, struct net *net, struct sk_buff *skb, u32 sip, u32 tip,
-+ unsigned char *from_hw, unsigned char *to_hw,
-+ struct net_device *idev, struct net_device *odev,
-+ struct dst_entry *dst);
-+
- int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir)
- {
- switch (dev->type) {
-@@ -338,7 +384,9 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
- struct net_device *dev = neigh->dev;
- __be32 target = *(__be32 *)neigh->primary_key;
- int probes = atomic_read(&neigh->probes);
-- struct in_device *in_dev;
-+ struct in_device *in_dev, *in_dev2;
-+ struct net_device *dev2;
-+ int mode;
- struct dst_entry *dst = NULL;
-
- rcu_read_lock();
-@@ -347,9 +395,22 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
- rcu_read_unlock();
- return;
- }
-- switch (IN_DEV_ARP_ANNOUNCE(in_dev)) {
-+ mode = IN_DEV_ARP_ANNOUNCE(in_dev);
-+ if (mode != 2 && skb &&
-+ (dev2 = __ip_dev_find(dev_net(dev), ip_hdr(skb)->saddr,
-+ false)) != NULL &&
-+ (saddr = ip_hdr(skb)->saddr,
-+ in_dev2 = __in_dev_get_rcu(dev2)) != NULL &&
-+ IN_DEV_HIDDEN(in_dev2)) {
-+ saddr = 0;
-+ goto get;
-+ }
-+
-+ switch (mode) {
- default:
- case 0: /* By default announce any local IP */
-+ if (saddr)
-+ break;
- if (skb && inet_addr_type_dev_table(dev_net(dev), dev,
- ip_hdr(skb)->saddr) == RTN_LOCAL)
- saddr = ip_hdr(skb)->saddr;
-@@ -357,9 +418,10 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
- case 1: /* Restrict announcements of saddr in same subnet */
- if (!skb)
- break;
-- saddr = ip_hdr(skb)->saddr;
-- if (inet_addr_type_dev_table(dev_net(dev), dev,
-- saddr) == RTN_LOCAL) {
-+ if (saddr ||
-+ (saddr = ip_hdr(skb)->saddr,
-+ inet_addr_type_dev_table(dev_net(dev), dev,
-+ saddr) == RTN_LOCAL)) {
- /* saddr should be known to target */
- if (inet_addr_onlink(in_dev, target, saddr))
- break;
-@@ -369,6 +431,8 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
- case 2: /* Avoid secondary IPs, get a primary/preferred one */
- break;
- }
-+
-+get:
- rcu_read_unlock();
-
- if (!saddr)
-@@ -390,8 +454,8 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb)
-
- if (skb && !(dev->priv_flags & IFF_XMIT_DST_RELEASE))
- dst = skb_dst(skb);
-- arp_send_dst(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr,
-- dst_hw, dev->dev_addr, NULL, dst);
-+ arpf_send(ARPA_TABLE_OUTPUT, dev_net(dev), skb, saddr, target, NULL,
-+ dst_hw, NULL, dev, dst);
- }
-
- static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip)
-@@ -448,6 +512,21 @@ static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev)
- return flag;
- }
-
-+static int arp_hidden(u32 tip, struct net_device *dev)
-+{
-+ struct net_device *dev2;
-+ struct in_device *in_dev2;
-+ int ret = 0;
-+
-+ if (!IPV4_DEVCONF_ALL(dev_net(dev), HIDDEN))
-+ return 0;
-+
-+ if ((dev2 = __ip_dev_find(dev_net(dev), tip, false)) && dev2 != dev &&
-+ (in_dev2 = __in_dev_get_rcu(dev2)) && IN_DEV_HIDDEN(in_dev2))
-+ ret = 1;
-+ return ret;
-+}
-+
- /*
- * Check if we can use proxy ARP for this path
- */
-@@ -808,9 +887,10 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
- if (sip == 0) {
- if (arp->ar_op == htons(ARPOP_REQUEST) &&
- inet_addr_type_dev_table(net, dev, tip) == RTN_LOCAL &&
-+ !arp_hidden(tip, dev) &&
- !arp_ignore(in_dev, sip, tip))
-- arp_send_dst(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip,
-- sha, dev->dev_addr, sha, reply_dst);
-+ arpf_send(ARPA_TABLE_INPUT, net, skb, sip, tip, sha,
-+ tha, dev, NULL, reply_dst);
- goto out_consume_skb;
- }
-
-@@ -826,13 +906,14 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
- dont_send = arp_ignore(in_dev, sip, tip);
- if (!dont_send && IN_DEV_ARPFILTER(in_dev))
- dont_send = arp_filter(sip, tip, dev);
-+ if (!dont_send && skb->pkt_type != PACKET_HOST)
-+ dont_send = arp_hidden(tip,dev);
- if (!dont_send) {
- n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
- if (n) {
-- arp_send_dst(ARPOP_REPLY, ETH_P_ARP,
-- sip, dev, tip, sha,
-- dev->dev_addr, sha,
-- reply_dst);
-+ arpf_send(ARPA_TABLE_INPUT, net, skb,
-+ sip, tip, sha, tha, dev,
-+ NULL, reply_dst);
- neigh_release(n);
- }
- }
-@@ -850,10 +931,9 @@ static int arp_process(struct net *net, struct sock *sk, struct sk_buff *skb)
- if (NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED ||
- skb->pkt_type == PACKET_HOST ||
- NEIGH_VAR(in_dev->arp_parms, PROXY_DELAY) == 0) {
-- arp_send_dst(ARPOP_REPLY, ETH_P_ARP,
-- sip, dev, tip, sha,
-- dev->dev_addr, sha,
-- reply_dst);
-+ arpf_send(ARPA_TABLE_FORWARD, net,
-+ skb, sip, tip, sha, tha, dev,
-+ rt->dst.dev, reply_dst);
- } else {
- pneigh_enqueue(&arp_tbl,
- in_dev->arp_parms, skb);
-@@ -1277,6 +1357,577 @@ void arp_ifdown(struct net_device *dev)
- }
-
-
-+static void arpf_destroy(struct arpf_node *afp)
-+{
-+ if (!afp->at_dead) {
-+ printk(KERN_ERR "Destroying alive arp table node %p from %08lx\n", afp,
-+ *(((unsigned long*)&afp)-1));
-+ return;
-+ }
-+ kmem_cache_free(arpf_cachep, afp);
-+}
-+
-+static inline void arpf_put(struct arpf_node *afp)
-+{
-+ if (atomic_dec_and_test(&afp->at_refcnt))
-+ arpf_destroy(afp);
-+}
-+
-+static inline struct arpf_node *
-+arpf_lookup(int table, struct sk_buff *skb, u32 sip, u32 tip,
-+ unsigned char *from_hw, unsigned char *to_hw,
-+ struct net_device *idev, struct net_device *odev)
-+{
-+ int sz_iif = idev? strlen(idev->name) : 0;
-+ int sz_oif = odev? strlen(odev->name) : 0;
-+ int alen;
-+ struct arpf_node *afp;
-+
-+ if (ARPA_TABLE_OUTPUT != table) {
-+ alen = idev->addr_len;
-+ } else {
-+ if (!from_hw) from_hw = odev->dev_addr;
-+ if (!to_hw) to_hw = odev->broadcast;
-+ alen = odev->addr_len;
-+ }
-+
-+ read_lock_bh(&arpf_lock);
-+ for (afp = arp_tabs[table]; afp; afp = afp->at_next) {
-+ if ((tip ^ afp->at_to) & afp->at_to_mask)
-+ continue;
-+ if ((sip ^ afp->at_from) & afp->at_from_mask)
-+ continue;
-+ if (afp->at_llfrom_len &&
-+ (afp->at_llfrom_len > alen ||
-+ memcmp(from_hw, afp->at_llfrom, afp->at_llfrom_len)))
-+ continue;
-+ if (afp->at_llto_len &&
-+ (afp->at_llto_len > alen ||
-+ memcmp(to_hw, afp->at_llto, afp->at_llto_len)))
-+ continue;
-+ if (afp->at_iif_len &&
-+ (afp->at_iif_len > sz_iif ||
-+ memcmp(afp->at_iif, idev->name, afp->at_iif_len) ||
-+ (sz_iif != afp->at_iif_len &&
-+ !(afp->at_flags & ARPM_F_WILDIIF))))
-+ continue;
-+ if (afp->at_oif_len &&
-+ (afp->at_oif_len > sz_oif ||
-+ memcmp(afp->at_oif, odev->name, afp->at_oif_len) ||
-+ (sz_oif != afp->at_oif_len &&
-+ !(afp->at_flags & ARPM_F_WILDOIF))))
-+ continue;
-+ if (afp->at_flags & ARPM_F_BROADCAST &&
-+ skb->pkt_type == PACKET_HOST)
-+ continue;
-+ if (afp->at_flags & ARPM_F_UNICAST &&
-+ skb->pkt_type != PACKET_HOST)
-+ continue;
-+ if (afp->at_llsrc_len && afp->at_llsrc_len != alen)
-+ continue;
-+ if (afp->at_lldst_len && afp->at_lldst_len != alen)
-+ continue;
-+ atomic_inc(&afp->at_refcnt);
-+ atomic_inc(&afp->at_packets);
-+ break;
-+ }
-+ read_unlock_bh(&arpf_lock);
-+ return afp;
-+}
-+
-+static void
-+arpf_send(int table, struct net *net, struct sk_buff *skb, u32 sip, u32 tip,
-+ unsigned char *from_hw, unsigned char *to_hw,
-+ struct net_device *idev, struct net_device *odev,
-+ struct dst_entry *dst)
-+{
-+ struct arpf_node *afp = NULL;
-+
-+ if (!arp_tabs[table] ||
-+ !net_eq(net, &init_net) ||
-+ !(afp = arpf_lookup(table, skb, sip, tip,
-+ from_hw, to_hw, idev, odev))) {
-+ switch (table) {
-+ case ARPA_TABLE_INPUT:
-+ case ARPA_TABLE_FORWARD:
-+ arp_send_dst(ARPOP_REPLY, ETH_P_ARP, sip, idev, tip,
-+ from_hw, idev->dev_addr, from_hw, dst);
-+ break;
-+ case ARPA_TABLE_OUTPUT:
-+ arp_send_dst(ARPOP_REQUEST, ETH_P_ARP, tip, odev, sip,
-+ to_hw, odev->dev_addr, NULL, dst);
-+ break;
-+ }
-+ return;
-+ }
-+
-+ /* deny? */
-+ if (!afp->at_action) goto out;
-+
-+ switch (table) {
-+ case ARPA_TABLE_INPUT:
-+ case ARPA_TABLE_FORWARD:
-+ arp_send_dst(ARPOP_REPLY, ETH_P_ARP, sip, idev, tip,
-+ afp->at_lldst_len?afp->at_lldst:from_hw,
-+ afp->at_llsrc_len?afp->at_llsrc:idev->dev_addr,
-+ afp->at_lldst_len?afp->at_lldst:from_hw, dst);
-+ break;
-+ case ARPA_TABLE_OUTPUT:
-+ if (afp->at_flags & ARPM_F_PREFSRC && afp->at_src == 0) {
-+ struct rtable *rt;
-+ struct flowi4 fl4 = { .daddr = tip,
-+ .flowi4_oif = odev->ifindex };
-+
-+ rt = ip_route_output_key(net, &fl4);
-+ if (IS_ERR(rt))
-+ break;
-+ sip = fl4.saddr;
-+ ip_rt_put(rt);
-+ if (!sip)
-+ break;
-+ }
-+ arp_send_dst(ARPOP_REQUEST, ETH_P_ARP, tip, odev,
-+ afp->at_src?:sip,
-+ afp->at_lldst_len?afp->at_lldst:to_hw,
-+ afp->at_llsrc_len?afp->at_llsrc:odev->dev_addr,
-+ NULL, dst);
-+ break;
-+ }
-+
-+out:
-+ arpf_put(afp);
-+}
-+
-+static int
-+arpf_fill_node(struct sk_buff *skb, u32 portid, u32 seq, unsigned flags,
-+ int event, int table, struct arpf_node *afp)
-+{
-+ struct arpmsg *am;
-+ struct nlmsghdr *nlh;
-+ u32 packets = atomic_read(&afp->at_packets);
-+
-+ nlh = nlmsg_put(skb, portid, seq, event, sizeof(*am), 0);
-+ if (nlh == NULL)
-+ return -ENOBUFS;
-+ nlh->nlmsg_flags = flags;
-+ am = nlmsg_data(nlh);
-+ am->arpm_family = AF_UNSPEC;
-+ am->arpm_table = table;
-+ am->arpm_action = afp->at_action;
-+ am->arpm_from_len = afp->at_from_len;
-+ am->arpm_to_len = afp->at_to_len;
-+ am->arpm_pref = afp->at_pref;
-+ am->arpm_flags = afp->at_flags;
-+ if (afp->at_from_len &&
-+ nla_put(skb, ARPA_FROM, 4, &afp->at_from))
-+ goto nla_put_failure;
-+ if (afp->at_to_len &&
-+ nla_put(skb, ARPA_TO, 4, &afp->at_to))
-+ goto nla_put_failure;
-+ if ((afp->at_src || afp->at_flags & ARPM_F_PREFSRC) &&
-+ nla_put(skb, ARPA_SRC, 4, &afp->at_src))
-+ goto nla_put_failure;
-+ if (afp->at_iif[0] &&
-+ nla_put(skb, ARPA_IIF, sizeof(afp->at_iif), afp->at_iif))
-+ goto nla_put_failure;
-+ if (afp->at_oif[0] &&
-+ nla_put(skb, ARPA_OIF, sizeof(afp->at_oif), afp->at_oif))
-+ goto nla_put_failure;
-+ if (afp->at_llfrom_len &&
-+ nla_put(skb, ARPA_LLFROM, afp->at_llfrom_len, afp->at_llfrom))
-+ goto nla_put_failure;
-+ if (afp->at_llto_len &&
-+ nla_put(skb, ARPA_LLTO, afp->at_llto_len, afp->at_llto))
-+ goto nla_put_failure;
-+ if (afp->at_llsrc_len &&
-+ nla_put(skb, ARPA_LLSRC, afp->at_llsrc_len, afp->at_llsrc))
-+ goto nla_put_failure;
-+ if (afp->at_lldst_len &&
-+ nla_put(skb, ARPA_LLDST, afp->at_lldst_len, afp->at_lldst))
-+ goto nla_put_failure;
-+ if (nla_put(skb, ARPA_PACKETS, 4, &packets))
-+ goto nla_put_failure;
-+ nlmsg_end(skb, nlh);
-+ return 0;
-+
-+nla_put_failure:
-+ nlmsg_cancel(skb, nlh);
-+ return -EMSGSIZE;
-+}
-+
-+static void
-+arpmsg_notify(struct sk_buff *oskb, struct nlmsghdr *nlh, int table,
-+ struct arpf_node *afp, int event)
-+{
-+ struct sk_buff *skb;
-+ u32 portid = oskb ? NETLINK_CB(oskb).portid : 0;
-+ int payload = sizeof(struct arpmsg) + 256;
-+ int err = -ENOBUFS;
-+
-+ skb = nlmsg_new(nlmsg_total_size(payload), GFP_KERNEL);
-+ if (!skb)
-+ goto errout;
-+
-+ err = arpf_fill_node(skb, portid, nlh->nlmsg_seq, 0, event, table, afp);
-+ if (err < 0) {
-+ kfree_skb(skb);
-+ goto errout;
-+ }
-+
-+ rtnl_notify(skb, &init_net, portid, RTNLGRP_ARP, nlh, GFP_KERNEL);
-+ return;
-+errout:
-+ if (err < 0)
-+ rtnl_set_sk_err(&init_net, RTNLGRP_ARP, err);
-+}
-+
-+static inline int
-+arpf_str_size(int a, struct nlattr **rta, int maxlen)
-+{
-+ int size = 0;
-+
-+ if (rta[a] && (size = nla_len(rta[a]))) {
-+ if (size > maxlen)
-+ size = maxlen;
-+ }
-+ return size;
-+}
-+
-+static inline int
-+arpf_get_str(int a, struct nlattr **rta, unsigned char *p,
-+ int maxlen, unsigned char *l)
-+{
-+ int size = arpf_str_size(a, rta, maxlen);
-+
-+ if (size) {
-+ memcpy(p, nla_data(rta[a]), size);
-+ *l = size;
-+ }
-+ return size;
-+}
-+
-+#define ARPF_MATCH_U32(ind, field) ( \
-+ (!rta[ind] && r->at_ ## field == 0) || \
-+ (rta[ind] && \
-+ *(u32*) nla_data(rta[ind]) == r->at_ ## field))
-+
-+#define ARPF_MATCH_STR(ind, field) ( \
-+ (!rta[ind] && r->at_ ## field ## _len == 0) || \
-+ (rta[ind] && r->at_ ## field ## _len && \
-+ r->at_ ## field ## _len < nla_len(rta[ind]) && \
-+ strcmp(nla_data(rta[ind]), r->at_ ## field) == 0))
-+
-+#define ARPF_MATCH_DATA(ind, field) ( \
-+ (!rta[ind] && r->at_ ## field ## _len == 0) || \
-+ (rta[ind] && r->at_ ## field ## _len && \
-+ r->at_ ## field ## _len == nla_len(rta[ind]) && \
-+ memcmp(nla_data(rta[ind]), &r->at_ ## field, \
-+ r->at_ ## field ## _len) == 0))
-+
-+/* RTM_NEWARPRULE/RTM_DELARPRULE/RTM_GETARPRULE */
-+
-+int arpf_rule_ctl(struct sk_buff *skb, struct nlmsghdr *n,
-+ struct netlink_ext_ack *extack)
-+{
-+ struct net *net = sock_net(skb->sk);
-+ struct nlattr *rta[ARPA_MAX + 1];
-+ struct arpmsg *am;
-+ struct arpf_node *r, **rp, **prevp = 0, **delp = 0, *newp = 0;
-+ unsigned pref = 1;
-+ int size, ret;
-+
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EPERM;
-+
-+ if (!net_eq(net, &init_net))
-+ return -EINVAL;
-+
-+ ret = nlmsg_parse(n, sizeof(struct arpmsg), rta, ARPA_MAX, NULL,
-+ extack);
-+ if (ret < 0)
-+ return ret;
-+
-+ am = nlmsg_data(n);
-+ ret = -EINVAL;
-+ if (am->arpm_table >= sizeof(arp_tabs)/sizeof(arp_tabs[0]))
-+ goto out;
-+ if (!((~am->arpm_flags) & (ARPM_F_BROADCAST|ARPM_F_UNICAST)))
-+ goto out;
-+ if (am->arpm_action > 1)
-+ goto out;
-+ if (am->arpm_to_len > 32 || am->arpm_from_len > 32)
-+ goto out;
-+ if (am->arpm_flags & ARPM_F_WILDIIF &&
-+ (!rta[ARPA_IIF] || !nla_len(rta[ARPA_IIF]) ||
-+ !*(char*) nla_data(rta[ARPA_IIF])))
-+ am->arpm_flags &= ~ARPM_F_WILDIIF;
-+ if (am->arpm_flags & ARPM_F_WILDOIF &&
-+ (!rta[ARPA_OIF] || !nla_len(rta[ARPA_OIF]) ||
-+ !*(char*) nla_data(rta[ARPA_OIF])))
-+ am->arpm_flags &= ~ARPM_F_WILDOIF;
-+ switch (am->arpm_table) {
-+ case ARPA_TABLE_INPUT:
-+ if (rta[ARPA_SRC] || rta[ARPA_OIF])
-+ goto out;
-+ break;
-+ case ARPA_TABLE_OUTPUT:
-+ if (rta[ARPA_IIF])
-+ goto out;
-+ if (am->arpm_flags & (ARPM_F_BROADCAST|ARPM_F_UNICAST))
-+ goto out;
-+ break;
-+ case ARPA_TABLE_FORWARD:
-+ if (rta[ARPA_SRC])
-+ goto out;
-+ break;
-+ }
-+ if (rta[ARPA_SRC] && !*(u32*) nla_data(rta[ARPA_SRC]))
-+ am->arpm_flags |= ARPM_F_PREFSRC;
-+ else
-+ am->arpm_flags &= ~ARPM_F_PREFSRC;
-+
-+ for (rp = &arp_tabs[am->arpm_table]; (r=*rp) != NULL; rp=&r->at_next) {
-+ if (pref < r->at_pref)
-+ prevp = rp;
-+ if (am->arpm_pref == r->at_pref ||
-+ (!am->arpm_pref &&
-+ am->arpm_to_len == r->at_to_len &&
-+ am->arpm_from_len == r->at_from_len &&
-+ !((am->arpm_flags ^ r->at_flags) &
-+ (ARPM_F_BROADCAST | ARPM_F_UNICAST |
-+ ARPM_F_WILDIIF | ARPM_F_WILDOIF)) &&
-+ ARPF_MATCH_U32(ARPA_TO, to) &&
-+ ARPF_MATCH_U32(ARPA_FROM, from) &&
-+ ARPF_MATCH_DATA(ARPA_LLFROM, llfrom) &&
-+ ARPF_MATCH_DATA(ARPA_LLTO, llto) &&
-+ ARPF_MATCH_STR(ARPA_IIF, iif) &&
-+ ARPF_MATCH_STR(ARPA_OIF, oif) &&
-+ (n->nlmsg_type != RTM_DELARPRULE ||
-+ /* DEL matches more keys */
-+ (am->arpm_flags == r->at_flags &&
-+ am->arpm_action == r->at_action &&
-+ ARPF_MATCH_U32(ARPA_SRC, src) &&
-+ ARPF_MATCH_DATA(ARPA_LLSRC, llsrc) &&
-+ ARPF_MATCH_DATA(ARPA_LLDST, lldst)
-+ )
-+ )
-+ )
-+ )
-+ break;
-+ if (am->arpm_pref && r->at_pref > am->arpm_pref) {
-+ r = NULL;
-+ break;
-+ }
-+ pref = r->at_pref+1;
-+ }
-+
-+ /*
-+ * r=NULL: *rp != NULL (stopped before next pref), pref: not valid
-+ * *rp == NULL (not found), pref: ready to use
-+ * r!=NULL: found, pref: not valid
-+ *
-+ * prevp=NULL: no free slot
-+ * prevp!=NULL: free slot for rule
-+ */
-+
-+ if (n->nlmsg_type == RTM_DELARPRULE) {
-+ if (!r)
-+ return -ESRCH;
-+ delp = rp;
-+ goto dequeue;
-+ }
-+
-+ if (r) {
-+ /* Existing rule */
-+ ret = -EEXIST;
-+ if (n->nlmsg_flags&NLM_F_EXCL)
-+ goto out;
-+
-+ if (n->nlmsg_flags&NLM_F_REPLACE) {
-+ pref = r->at_pref;
-+ prevp = delp = rp;
-+ goto replace;
-+ }
-+ }
-+
-+ if (n->nlmsg_flags&NLM_F_APPEND) {
-+ if (r) {
-+ pref = r->at_pref+1;
-+ for (rp=&r->at_next; (r=*rp) != NULL; rp=&r->at_next) {
-+ if (pref != r->at_pref)
-+ break;
-+ pref ++;
-+ }
-+ ret = -EBUSY;
-+ if (!pref)
-+ goto out;
-+ } else if (am->arpm_pref)
-+ pref = am->arpm_pref;
-+ prevp = rp;
-+ }
-+
-+ if (!(n->nlmsg_flags&NLM_F_CREATE)) {
-+ ret = -ENOENT;
-+ if (n->nlmsg_flags&NLM_F_EXCL || r)
-+ ret = 0;
-+ goto out;
-+ }
-+
-+ if (!(n->nlmsg_flags&NLM_F_APPEND)) {
-+ if (!prevp) {
-+ ret = -EBUSY;
-+ if (r || *rp ||
-+ (!am->arpm_pref && arp_tabs[am->arpm_table]))
-+ goto out;
-+ prevp = rp;
-+ pref = am->arpm_pref? : 99;
-+ } else {
-+ if (r || !am->arpm_pref) {
-+ pref = (*prevp)->at_pref - 1;
-+ if (am->arpm_pref && am->arpm_pref < pref)
-+ pref = am->arpm_pref;
-+ } else {
-+ prevp = rp;
-+ pref = am->arpm_pref;
-+ }
-+ }
-+ }
-+
-+replace:
-+
-+ ret = -ENOMEM;
-+ r = kmem_cache_alloc(arpf_cachep, GFP_KERNEL);
-+ if (!r)
-+ return ret;
-+ memset(r, 0, sizeof(*r));
-+
-+ arpf_get_str(ARPA_LLFROM, rta, r->at_llfrom, MAX_ADDR_LEN,
-+ &r->at_llfrom_len);
-+ arpf_get_str(ARPA_LLTO, rta, r->at_llto, MAX_ADDR_LEN,
-+ &r->at_llto_len);
-+ arpf_get_str(ARPA_LLSRC, rta, r->at_llsrc, MAX_ADDR_LEN,
-+ &r->at_llsrc_len);
-+ arpf_get_str(ARPA_LLDST, rta, r->at_lldst, MAX_ADDR_LEN,
-+ &r->at_lldst_len);
-+
-+ if (delp)
-+ r->at_next = (*delp)->at_next;
-+ else if (*prevp)
-+ r->at_next = *prevp;
-+
-+ r->at_pref = pref;
-+ r->at_from_len = am->arpm_from_len;
-+ r->at_from_mask = inet_make_mask(r->at_from_len);
-+ if (rta[ARPA_FROM])
-+ r->at_from = *(u32*) nla_data(rta[ARPA_FROM]);
-+ r->at_from &= r->at_from_mask;
-+ r->at_to_len = am->arpm_to_len;
-+ r->at_to_mask = inet_make_mask(r->at_to_len);
-+ if (rta[ARPA_TO])
-+ r->at_to = *(u32*) nla_data(rta[ARPA_TO]);
-+ r->at_to &= r->at_to_mask;
-+ if (rta[ARPA_SRC])
-+ r->at_src = *(u32*) nla_data(rta[ARPA_SRC]);
-+ if (rta[ARPA_PACKETS]) {
-+ u32 packets = *(u32*) nla_data(rta[ARPA_PACKETS]);
-+ atomic_set(&r->at_packets, packets);
-+ }
-+ atomic_set(&r->at_refcnt, 1);
-+ r->at_flags = am->arpm_flags;
-+ r->at_action = am->arpm_action;
-+
-+ if (rta[ARPA_IIF] && (size = nla_len(rta[ARPA_IIF]))) {
-+ if (size >= sizeof(r->at_iif))
-+ size = sizeof(r->at_iif)-1;
-+ memcpy(r->at_iif, nla_data(rta[ARPA_IIF]), size);
-+ r->at_iif_len = strlen(r->at_iif);
-+ }
-+ if (rta[ARPA_OIF] && (size = nla_len(rta[ARPA_OIF]))) {
-+ if (size >= sizeof(r->at_oif))
-+ size = sizeof(r->at_oif)-1;
-+ memcpy(r->at_oif, nla_data(rta[ARPA_OIF]), size);
-+ r->at_oif_len = strlen(r->at_oif);
-+ }
-+
-+ newp = r;
-+
-+dequeue:
-+
-+ if (delp) {
-+ r = *delp;
-+ write_lock_bh(&arpf_lock);
-+ if (newp) {
-+ if (!rta[ARPA_PACKETS])
-+ atomic_set(&newp->at_packets,
-+ atomic_read(&r->at_packets));
-+ *delp = newp;
-+ } else {
-+ *delp = r->at_next;
-+ }
-+ r->at_dead = 1;
-+ write_unlock_bh(&arpf_lock);
-+ arpmsg_notify(skb, n, am->arpm_table, r, RTM_DELARPRULE);
-+ arpf_put(r);
-+ prevp = 0;
-+ }
-+
-+ if (newp) {
-+ if (prevp) {
-+ write_lock_bh(&arpf_lock);
-+ *prevp = newp;
-+ write_unlock_bh(&arpf_lock);
-+ }
-+ arpmsg_notify(skb, n, am->arpm_table, newp, RTM_NEWARPRULE);
-+ }
-+
-+ ret = 0;
-+
-+out:
-+ return ret;
-+}
-+
-+int arpf_dump_table(int t, struct sk_buff *skb, struct netlink_callback *cb)
-+{
-+ int idx, ret = -1;
-+ struct arpf_node *afp;
-+ int s_idx = cb->args[1];
-+
-+ for (idx=0, afp = arp_tabs[t]; afp; afp = afp->at_next, idx++) {
-+ if (idx < s_idx)
-+ continue;
-+ if (arpf_fill_node(skb, NETLINK_CB(cb->skb).portid,
-+ cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWARPRULE, t, afp) < 0)
-+ goto out;
-+ }
-+
-+ ret = skb->len;
-+
-+out:
-+ cb->args[1] = idx;
-+
-+ return ret;
-+}
-+
-+int arpf_dump_rules(struct sk_buff *skb, struct netlink_callback *cb)
-+{
-+ int idx;
-+ int s_idx = cb->args[0];
-+
-+ read_lock_bh(&arpf_lock);
-+ for (idx = 0; idx < sizeof(arp_tabs)/sizeof(arp_tabs[0]); idx++) {
-+ if (idx < s_idx)
-+ continue;
-+ if (idx > s_idx)
-+ memset(&cb->args[1], 0, sizeof(cb->args)-1*sizeof(cb->args[0]));
-+ if (arpf_dump_table(idx, skb, cb) < 0)
-+ break;
-+ }
-+ read_unlock_bh(&arpf_lock);
-+ cb->args[0] = idx;
-+
-+ return skb->len;
-+}
-+
- /*
- * Called once on startup.
- */
-@@ -1290,6 +1941,16 @@ static int arp_proc_init(void);
-
- void __init arp_init(void)
- {
-+ arpf_cachep = kmem_cache_create("ip_arpf_cache",
-+ sizeof(struct arpf_node), 0,
-+ SLAB_HWCACHE_ALIGN, NULL);
-+ if (!arpf_cachep)
-+ panic("IP: failed to allocate ip_arpf_cache\n");
-+
-+ rtnl_register(PF_UNSPEC, RTM_NEWARPRULE, arpf_rule_ctl, NULL, 0);
-+ rtnl_register(PF_UNSPEC, RTM_DELARPRULE, arpf_rule_ctl, NULL, 0);
-+ rtnl_register(PF_UNSPEC, RTM_GETARPRULE, NULL, arpf_dump_rules, 0);
-+
- neigh_table_init(NEIGH_ARP_TABLE, &arp_tbl);
-
- dev_add_pack(&arp_packet_type);
-diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
-index 40f001782c1b..6f0490e5604e 100644
---- a/net/ipv4/devinet.c
-+++ b/net/ipv4/devinet.c
-@@ -1284,9 +1284,14 @@ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
- if (!in_dev)
- continue;
-
-- addr = in_dev_select_addr(in_dev, scope);
-- if (addr)
-- goto out_unlock;
-+ for_primary_ifa(in_dev) {
-+ if (!IN_DEV_HIDDEN(in_dev) &&
-+ ifa->ifa_scope != RT_SCOPE_LINK &&
-+ ifa->ifa_scope <= scope) {
-+ addr = ifa->ifa_local;
-+ goto out_unlock;
-+ }
-+ } endfor_ifa(in_dev);
- }
- out_unlock:
- rcu_read_unlock();
-@@ -2252,13 +2257,16 @@ static struct devinet_sysctl_table {
- DEVINET_SYSCTL_RW_ENTRY(SEND_REDIRECTS, "send_redirects"),
- DEVINET_SYSCTL_RW_ENTRY(ACCEPT_SOURCE_ROUTE,
- "accept_source_route"),
-+ DEVINET_SYSCTL_RW_ENTRY(FORWARD_SHARED, "forward_shared"),
- DEVINET_SYSCTL_RW_ENTRY(ACCEPT_LOCAL, "accept_local"),
- DEVINET_SYSCTL_RW_ENTRY(SRC_VMARK, "src_valid_mark"),
- DEVINET_SYSCTL_RW_ENTRY(PROXY_ARP, "proxy_arp"),
- DEVINET_SYSCTL_RW_ENTRY(MEDIUM_ID, "medium_id"),
-+ DEVINET_SYSCTL_RW_ENTRY(RP_FILTER_MASK, "rp_filter_mask"),
- DEVINET_SYSCTL_RW_ENTRY(BOOTP_RELAY, "bootp_relay"),
- DEVINET_SYSCTL_RW_ENTRY(LOG_MARTIANS, "log_martians"),
- DEVINET_SYSCTL_RW_ENTRY(TAG, "tag"),
-+ DEVINET_SYSCTL_RW_ENTRY(HIDDEN, "hidden"),
- DEVINET_SYSCTL_RW_ENTRY(ARPFILTER, "arp_filter"),
- DEVINET_SYSCTL_RW_ENTRY(ARP_ANNOUNCE, "arp_announce"),
- DEVINET_SYSCTL_RW_ENTRY(ARP_IGNORE, "arp_ignore"),
-diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
-index aa597b2c1429..70c825bd7b62 100644
---- a/net/ipv4/fib_frontend.c
-+++ b/net/ipv4/fib_frontend.c
-@@ -51,6 +51,8 @@
-
- #ifndef CONFIG_IP_MULTIPLE_TABLES
-
-+#define FIB_RES_TABLE(r) (RT_TABLE_MAIN)
-+
- static int __net_init fib4_rules_init(struct net *net)
- {
- struct fib_table *local_table, *main_table;
-@@ -80,6 +82,8 @@ static bool fib4_has_custom_rules(struct net *net)
- }
- #else
-
-+#define FIB_RES_TABLE(r) (fib_result_table(r))
-+
- struct fib_table *fib_new_table(struct net *net, u32 id)
- {
- struct fib_table *tb, *alias = NULL;
-@@ -324,11 +328,17 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb)
- */
- static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
- u8 tos, int oif, struct net_device *dev,
-- int rpf, struct in_device *idev, u32 *itag)
-+ int rpf, struct in_device *idev, u32 *itag,
-+ int our)
- {
-+ u32 table;
-+ unsigned char prefixlen;
-+ unsigned char scope;
- int ret, no_addr;
- struct fib_result res;
- struct flowi4 fl4;
-+ int fwdsh;
-+ unsigned int rpf_mask;
- struct net *net = dev_net(dev);
- bool dev_match;
-
-@@ -343,16 +353,24 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
- fl4.flowi4_tun_key.tun_id = 0;
- fl4.flowi4_flags = 0;
- fl4.flowi4_uid = sock_net_uid(net, NULL);
-+ fl4.fl4_gw = 0;
-
- no_addr = idev->ifa_list == NULL;
-
-+ fwdsh = IN_DEV_FORWARD_SHARED(idev);
- fl4.flowi4_mark = IN_DEV_SRC_VMARK(idev) ? skb->mark : 0;
-+ rpf_mask = IN_DEV_RPFILTER_MASK(idev);
-
- trace_fib_validate_source(dev, &fl4);
-
- if (fib_lookup(net, &fl4, &res, 0))
- goto last_resort;
-- if (res.type != RTN_UNICAST &&
-+ if (fwdsh) {
-+ fwdsh = (res.type == RTN_LOCAL && !our);
-+ if (fwdsh)
-+ rpf = 0;
-+ }
-+ if (res.type != RTN_UNICAST && !fwdsh &&
- (res.type != RTN_LOCAL || !IN_DEV_ACCEPT_LOCAL(idev)))
- goto e_inval;
- fib_combine_itag(itag, &res);
-@@ -378,17 +396,36 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
- ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
- return ret;
- }
-+ if (rpf_mask && rpf) {
-+ int omi = 0;
-+
-+ idev = __in_dev_get_rcu(FIB_RES_DEV(res));
-+ if (idev)
-+ omi = IN_DEV_MEDIUM_ID(idev);
-+ if (omi >= 1 && omi <= 31 && ((1 << omi) & rpf_mask))
-+ rpf = 0;
-+ }
- if (no_addr)
- goto last_resort;
-- if (rpf == 1)
-- goto e_rpf;
-+ table = FIB_RES_TABLE(&res);
-+ prefixlen = res.prefixlen;
-+ scope = res.scope;
- fl4.flowi4_oif = dev->ifindex;
-+ if (fwdsh)
-+ fl4.flowi4_iif = LOOPBACK_IFINDEX;
-
- ret = 0;
- if (fib_lookup(net, &fl4, &res, FIB_LOOKUP_IGNORE_LINKSTATE) == 0) {
-- if (res.type == RTN_UNICAST)
-+ if (res.type == RTN_UNICAST &&
-+ ((table == FIB_RES_TABLE(&res) &&
-+ res.prefixlen >= prefixlen && res.scope >= scope) ||
-+ !rpf)) {
- ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
-+ return ret;
-+ }
- }
-+ if (rpf == 1)
-+ goto e_rpf;
- return ret;
-
- last_resort:
-@@ -406,7 +443,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
- /* Ignore rp_filter for packets protected by IPsec. */
- int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
- u8 tos, int oif, struct net_device *dev,
-- struct in_device *idev, u32 *itag)
-+ struct in_device *idev, u32 *itag, int our)
- {
- int r = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(idev);
- struct net *net = dev_net(dev);
-@@ -431,7 +468,8 @@ int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
- }
-
- full_check:
-- return __fib_validate_source(skb, src, dst, tos, oif, dev, r, idev, itag);
-+ return __fib_validate_source(skb, src, dst, tos, oif, dev, r, idev,
-+ itag, our);
- }
-
- static inline __be32 sk_extract_addr(struct sockaddr *addr)
-@@ -1179,9 +1217,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
- switch (event) {
- case NETDEV_UP:
- fib_add_ifaddr(ifa);
--#ifdef CONFIG_IP_ROUTE_MULTIPATH
- fib_sync_up(dev, RTNH_F_DEAD);
--#endif
- atomic_inc(&net->ipv4.dev_addr_genid);
- rt_cache_flush(dev_net(dev));
- break;
-@@ -1224,9 +1260,7 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
- for_ifa(in_dev) {
- fib_add_ifaddr(ifa);
- } endfor_ifa(in_dev);
--#ifdef CONFIG_IP_ROUTE_MULTIPATH
- fib_sync_up(dev, RTNH_F_DEAD);
--#endif
- atomic_inc(&net->ipv4.dev_addr_genid);
- rt_cache_flush(net);
- break;
-diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
-index 35d646a62ad4..35717a34311c 100644
---- a/net/ipv4/fib_rules.c
-+++ b/net/ipv4/fib_rules.c
-@@ -78,6 +78,11 @@ unsigned int fib4_rules_seq_read(struct net *net)
- return fib_rules_seq_read(net, AF_INET);
- }
-
-+u32 fib_result_table(struct fib_result *res)
-+{
-+ return res->table ? res->table->tb_id : RT_TABLE_UNSPEC;
-+}
-+
- int __fib_lookup(struct net *net, struct flowi4 *flp,
- struct fib_result *res, unsigned int flags)
- {
-diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
-index 19f7d8cd4875..532f060ed740 100644
---- a/net/ipv4/fib_semantics.c
-+++ b/net/ipv4/fib_semantics.c
-@@ -53,6 +53,7 @@ static struct hlist_head *fib_info_hash;
- static struct hlist_head *fib_info_laddrhash;
- static unsigned int fib_info_hash_size;
- static unsigned int fib_info_cnt;
-+DEFINE_RWLOCK(fib_nhflags_lock);
-
- #define DEVINDEX_HASHBITS 8
- #define DEVINDEX_HASHSIZE (1U << DEVINDEX_HASHBITS)
-@@ -435,28 +436,70 @@ void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
-
- static int fib_detect_death(struct fib_info *fi, int order,
- struct fib_info **last_resort, int *last_idx,
-- int dflt)
-+ int dflt, int *last_nhsel,
-+ const struct flowi4 *flp)
- {
- struct neighbour *n;
-- int state = NUD_NONE;
-+ int nhsel;
-+ int state;
-+ struct fib_nh * nh;
-+ __be32 dst;
-+ int flag, dead = 1;
-
-- n = neigh_lookup(&arp_tbl, &fi->fib_nh[0].nh_gw, fi->fib_dev);
-- if (n) {
-- state = n->nud_state;
-- neigh_release(n);
-- } else {
-- return 0;
-- }
-- if (state == NUD_REACHABLE)
-- return 0;
-- if ((state & NUD_VALID) && order != dflt)
-- return 0;
-- if ((state & NUD_VALID) ||
-- (*last_idx < 0 && order > dflt && state != NUD_INCOMPLETE)) {
-- *last_resort = fi;
-- *last_idx = order;
-+ /* change_nexthops(fi) { */
-+ for (nhsel = 0, nh = fi->fib_nh; nhsel < fi->fib_nhs; nh++, nhsel++) {
-+ if (flp->flowi4_oif && flp->flowi4_oif != nh->nh_oif)
-+ continue;
-+ if (flp->fl4_gw && flp->fl4_gw != nh->nh_gw && nh->nh_gw &&
-+ nh->nh_scope == RT_SCOPE_LINK)
-+ continue;
-+ if (nh->nh_flags & RTNH_F_DEAD)
-+ continue;
-+
-+ flag = 0;
-+ if (nh->nh_dev->flags & IFF_NOARP) {
-+ dead = 0;
-+ goto setfl;
-+ }
-+
-+ dst = nh->nh_gw;
-+ if (!nh->nh_gw || nh->nh_scope != RT_SCOPE_LINK)
-+ dst = flp->daddr;
-+
-+ state = NUD_NONE;
-+ n = neigh_lookup(&arp_tbl, &dst, nh->nh_dev);
-+ if (n) {
-+ state = n->nud_state;
-+ neigh_release(n);
-+ }
-+ if (state == NUD_REACHABLE ||
-+ ((state & NUD_VALID) && order != dflt)) {
-+ dead = 0;
-+ goto setfl;
-+ }
-+ if (!(state & NUD_VALID))
-+ flag = 1;
-+ if (!dead)
-+ goto setfl;
-+ if ((state & NUD_VALID) ||
-+ (*last_idx < 0 && order >= dflt)) {
-+ *last_resort = fi;
-+ *last_idx = order;
-+ *last_nhsel = nhsel;
-+ }
-+
-+ setfl:
-+
-+ read_lock_bh(&fib_nhflags_lock);
-+ if (flag)
-+ nh->nh_flags |= RTNH_F_SUSPECT;
-+ else
-+ nh->nh_flags &= ~RTNH_F_SUSPECT;
-+ read_unlock_bh(&fib_nhflags_lock);
- }
-- return 1;
-+ /* } endfor_nexthops(fi) */
-+
-+ return dead;
- }
-
- #ifdef CONFIG_IP_ROUTE_MULTIPATH
-@@ -783,6 +826,7 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_nh *nh,
- int err = 0;
- struct net *net;
- struct net_device *dev;
-+ struct fib_info *fi = nh->nh_parent;
-
- net = cfg->fc_nlinfo.nl_net;
- if (nh->nh_gw) {
-@@ -800,9 +844,12 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_nh *nh,
- if (!dev)
- return -ENODEV;
- if (!(dev->flags & IFF_UP)) {
-- NL_SET_ERR_MSG(extack,
-- "Nexthop device is not up");
-- return -ENETDOWN;
-+ if (fi->fib_protocol != RTPROT_STATIC) {
-+ NL_SET_ERR_MSG(extack,
-+ "Nexthop device is not up");
-+ return -ENETDOWN;
-+ }
-+ nh->nh_flags |= RTNH_F_DEAD;
- }
- addr_type = inet_addr_type_dev_table(net, dev, nh->nh_gw);
- if (addr_type != RTN_UNICAST) {
-@@ -847,31 +894,57 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_nh *nh,
- err = fib_lookup(net, &fl4, &res,
- FIB_LOOKUP_IGNORE_LINKSTATE);
- }
-+ }
-+ if (err) {
-+ struct in_device *in_dev;
-
-- if (err) {
-+ if (err != -ENETUNREACH ||
-+ fi->fib_protocol != RTPROT_STATIC) {
- NL_SET_ERR_MSG(extack,
- "Nexthop has invalid gateway");
-- rcu_read_unlock();
-- return err;
-+ goto out;
- }
-+
-+ in_dev = inetdev_by_index(net, nh->nh_oif);
-+ if (in_dev == NULL ||
-+ in_dev->dev->flags & IFF_UP) {
-+ NL_SET_ERR_MSG(extack,
-+ "Device for nexthop is not up");
-+ goto out;
-+ }
-+ nh->nh_flags |= RTNH_F_DEAD;
-+ nh->nh_scope = RT_SCOPE_LINK;
-+ nh->nh_dev = in_dev->dev;
-+ dev_hold(nh->nh_dev);
-+ } else {
-+ err = -EINVAL;
-+ if (res.type != RTN_UNICAST && res.type != RTN_LOCAL) {
-+ NL_SET_ERR_MSG(extack,
-+ "Nexthop has invalid gateway");
-+ goto out;
-+ }
-+ nh->nh_scope = res.scope;
-+ nh->nh_oif = FIB_RES_OIF(res);
-+ nh->nh_dev = dev = FIB_RES_DEV(res);
-+ if (!dev) {
-+ NL_SET_ERR_MSG(extack,
-+ "No egress device for nexthop gateway");
-+ goto out;
-+ }
-+ dev_hold(dev);
-+ if (!netif_carrier_ok(dev))
-+ nh->nh_flags |= RTNH_F_LINKDOWN;
-+ if (!(nh->nh_dev->flags & IFF_UP)) {
-+ if (fi->fib_protocol != RTPROT_STATIC) {
-+ err = -ENETDOWN;
-+ NL_SET_ERR_MSG(extack,
-+ "Device for nexthop is not up");
-+ goto out;
-+ }
-+ nh->nh_flags |= RTNH_F_DEAD;
-+ }
-+ err = 0;
- }
-- err = -EINVAL;
-- if (res.type != RTN_UNICAST && res.type != RTN_LOCAL) {
-- NL_SET_ERR_MSG(extack, "Nexthop has invalid gateway");
-- goto out;
-- }
-- nh->nh_scope = res.scope;
-- nh->nh_oif = FIB_RES_OIF(res);
-- nh->nh_dev = dev = FIB_RES_DEV(res);
-- if (!dev) {
-- NL_SET_ERR_MSG(extack,
-- "No egress device for nexthop gateway");
-- goto out;
-- }
-- dev_hold(dev);
-- if (!netif_carrier_ok(dev))
-- nh->nh_flags |= RTNH_F_LINKDOWN;
-- err = (dev->flags & IFF_UP) ? 0 : -ENETDOWN;
- } else {
- struct in_device *in_dev;
-
-@@ -887,8 +960,12 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_nh *nh,
- goto out;
- err = -ENETDOWN;
- if (!(in_dev->dev->flags & IFF_UP)) {
-- NL_SET_ERR_MSG(extack, "Device for nexthop is not up");
-- goto out;
-+ if (fi->fib_protocol != RTPROT_STATIC) {
-+ NL_SET_ERR_MSG(extack,
-+ "Device for nexthop is not up");
-+ goto out;
-+ }
-+ nh->nh_flags |= RTNH_F_DEAD;
- }
- nh->nh_dev = in_dev->dev;
- dev_hold(nh->nh_dev);
-@@ -1539,10 +1616,15 @@ int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force)
- prev_fi = fi;
- dead = 0;
- change_nexthops(fi) {
-- if (nexthop_nh->nh_flags & RTNH_F_DEAD)
-- dead++;
-- else if (nexthop_nh->nh_dev == dev &&
-- nexthop_nh->nh_scope != scope) {
-+ if (nexthop_nh->nh_flags & RTNH_F_DEAD) {
-+ if (fi->fib_protocol != RTPROT_STATIC ||
-+ nexthop_nh->nh_dev == NULL ||
-+ __in_dev_get_rtnl(nexthop_nh->nh_dev) == NULL ||
-+ nexthop_nh->nh_dev->flags&IFF_UP)
-+ dead++;
-+ } else if (nexthop_nh->nh_dev == dev &&
-+ nexthop_nh->nh_scope != scope) {
-+ write_lock_bh(&fib_nhflags_lock);
- switch (event) {
- case NETDEV_DOWN:
- case NETDEV_UNREGISTER:
-@@ -1554,7 +1636,11 @@ int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force)
- }
- call_fib_nh_notifiers(nexthop_nh,
- FIB_EVENT_NH_DEL);
-- dead++;
-+ write_unlock_bh(&fib_nhflags_lock);
-+ if (fi->fib_protocol != RTPROT_STATIC ||
-+ force ||
-+ __in_dev_get_rtnl(dev) == NULL)
-+ dead++;
- }
- #ifdef CONFIG_IP_ROUTE_MULTIPATH
- if (event == NETDEV_UNREGISTER &&
-@@ -1584,13 +1670,13 @@ int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force)
- }
-
- /* Must be invoked inside of an RCU protected region. */
--static void fib_select_default(const struct flowi4 *flp, struct fib_result *res)
-+void fib_select_default(const struct flowi4 *flp, struct fib_result *res)
- {
- struct fib_info *fi = NULL, *last_resort = NULL;
- struct hlist_head *fa_head = res->fa_head;
- struct fib_table *tb = res->table;
- u8 slen = 32 - res->prefixlen;
-- int order = -1, last_idx = -1;
-+ int order = -1, last_idx = -1, last_nhsel = 0;
- struct fib_alias *fa, *fa1 = NULL;
- u32 last_prio = res->fi->fib_priority;
- u8 last_tos = 0;
-@@ -1618,9 +1704,6 @@ static void fib_select_default(const struct flowi4 *flp, struct fib_result *res)
- if (next_fi->fib_scope != res->scope ||
- fa->fa_type != RTN_UNICAST)
- continue;
-- if (!next_fi->fib_nh[0].nh_gw ||
-- next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
-- continue;
-
- fib_alias_accessed(fa);
-
-@@ -1629,7 +1712,8 @@ static void fib_select_default(const struct flowi4 *flp, struct fib_result *res)
- break;
- fa1 = fa;
- } else if (!fib_detect_death(fi, order, &last_resort,
-- &last_idx, fa1->fa_default)) {
-+ &last_idx, fa1->fa_default,
-+ &last_nhsel, flp)) {
- fib_result_assign(res, fi);
- fa1->fa_default = order;
- goto out;
-@@ -1639,28 +1723,39 @@ static void fib_select_default(const struct flowi4 *flp, struct fib_result *res)
- }
-
- if (order <= 0 || !fi) {
-+ if (fi && fi->fib_nhs > 1 &&
-+ fib_detect_death(fi, order, &last_resort, &last_idx,
-+ fa1->fa_default, &last_nhsel, flp) &&
-+ last_resort == fi) {
-+ read_lock_bh(&fib_nhflags_lock);
-+ fi->fib_nh[last_nhsel].nh_flags &= ~RTNH_F_SUSPECT;
-+ read_unlock_bh(&fib_nhflags_lock);
-+ }
- if (fa1)
- fa1->fa_default = -1;
- goto out;
- }
-
- if (!fib_detect_death(fi, order, &last_resort, &last_idx,
-- fa1->fa_default)) {
-+ fa1->fa_default, &last_nhsel, flp)) {
- fib_result_assign(res, fi);
- fa1->fa_default = order;
- goto out;
- }
-
-- if (last_idx >= 0)
-+ if (last_idx >= 0) {
- fib_result_assign(res, last_resort);
-+ read_lock_bh(&fib_nhflags_lock);
-+ last_resort->fib_nh[last_nhsel].nh_flags &= ~RTNH_F_SUSPECT;
-+ read_unlock_bh(&fib_nhflags_lock);
-+ }
- fa1->fa_default = last_idx;
- out:
- return;
- }
-
- /*
-- * Dead device goes up. We wake up dead nexthops.
-- * It takes sense only on multipath routes.
-+ * Dead device goes up or new address is added. We wake up dead nexthops.
- */
- int fib_sync_up(struct net_device *dev, unsigned int nh_flags)
- {
-@@ -1668,8 +1763,10 @@ int fib_sync_up(struct net_device *dev, unsigned int nh_flags)
- unsigned int hash;
- struct hlist_head *head;
- struct fib_nh *nh;
-- int ret;
-+ struct fib_result res;
-+ int ret, rep;
-
-+repeat:
- if (!(dev->flags & IFF_UP))
- return 0;
-
-@@ -1684,6 +1781,7 @@ int fib_sync_up(struct net_device *dev, unsigned int nh_flags)
- hash = fib_devindex_hashfn(dev->ifindex);
- head = &fib_info_devhash[hash];
- ret = 0;
-+ rep = 0;
-
- hlist_for_each_entry(nh, head, nh_hash) {
- struct fib_info *fi = nh->nh_parent;
-@@ -1696,16 +1794,37 @@ int fib_sync_up(struct net_device *dev, unsigned int nh_flags)
- prev_fi = fi;
- alive = 0;
- change_nexthops(fi) {
-- if (!(nexthop_nh->nh_flags & nh_flags)) {
-- alive++;
-+ if (!(nexthop_nh->nh_flags & nh_flags))
- continue;
-- }
- if (!nexthop_nh->nh_dev ||
- !(nexthop_nh->nh_dev->flags & IFF_UP))
- continue;
- if (nexthop_nh->nh_dev != dev ||
- !__in_dev_get_rtnl(dev))
- continue;
-+ if ((nh_flags & RTNH_F_DEAD) && nexthop_nh->nh_gw &&
-+ fi->fib_protocol == RTPROT_STATIC) {
-+ struct flowi4 fl4 = {
-+ .daddr = nexthop_nh->nh_gw,
-+ .flowi4_scope = nexthop_nh->nh_scope,
-+ .flowi4_oif = nexthop_nh->nh_oif,
-+ };
-+
-+ rcu_read_lock();
-+ if (fib_lookup(dev_net(dev), &fl4, &res,
-+ FIB_LOOKUP_IGNORE_LINKSTATE) != 0) {
-+ rcu_read_unlock();
-+ continue;
-+ }
-+ if (res.type != RTN_UNICAST &&
-+ res.type != RTN_LOCAL) {
-+ rcu_read_unlock();
-+ continue;
-+ }
-+ nexthop_nh->nh_scope = res.scope;
-+ rcu_read_unlock();
-+ rep = 1;
-+ }
- alive++;
- nexthop_nh->nh_flags &= ~nh_flags;
- call_fib_nh_notifiers(nexthop_nh, FIB_EVENT_NH_ADD);
-@@ -1718,6 +1837,8 @@ int fib_sync_up(struct net_device *dev, unsigned int nh_flags)
-
- fib_rebalance(fi);
- }
-+ if (rep)
-+ goto repeat;
-
- return ret;
- }
-@@ -1772,20 +1893,17 @@ void fib_select_path(struct net *net, struct fib_result *res,
- bool oif_check;
-
- oif_check = (fl4->flowi4_oif == 0 ||
-- fl4->flowi4_flags & FLOWI_FLAG_SKIP_NH_OIF);
-+ fl4->flowi4_flags & FLOWI_FLAG_SKIP_NH_OIF || 1);
-
-+ if (res->type == RTN_UNICAST)
-+ fib_select_default(fl4, res);
- #ifdef CONFIG_IP_ROUTE_MULTIPATH
- if (res->fi->fib_nhs > 1 && oif_check) {
- int h = fib_multipath_hash(res->fi, fl4, skb);
-
- fib_select_multipath(res, h);
- }
-- else
- #endif
-- if (!res->prefixlen &&
-- res->table->tb_num_default > 1 &&
-- res->type == RTN_UNICAST && oif_check)
-- fib_select_default(fl4, res);
-
- if (!fl4->saddr)
- fl4->saddr = FIB_RES_PREFSRC(net, *res);
-diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
-index 5530cd6fdbc7..d939ea676230 100644
---- a/net/ipv4/fib_trie.c
-+++ b/net/ipv4/fib_trie.c
-@@ -1458,6 +1458,9 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
- if (flp->flowi4_oif &&
- flp->flowi4_oif != nh->nh_oif)
- continue;
-+ if (flp->fl4_gw && flp->fl4_gw != nh->nh_gw &&
-+ nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK)
-+ continue;
- }
-
- if (!(fib_flags & FIB_LOOKUP_NOREF))
-diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
-index 0f7255cc65ee..a033de8ed368 100644
---- a/net/ipv4/netfilter/iptable_nat.c
-+++ b/net/ipv4/netfilter/iptable_nat.c
-@@ -92,6 +92,13 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
- .hooknum = NF_INET_LOCAL_OUT,
- .priority = NF_IP_PRI_NAT_DST,
- },
-+ /* Before routing, route before mangling */
-+ {
-+ .hook = ip_nat_route_input,
-+ .pf = NFPROTO_IPV4,
-+ .hooknum = NF_INET_PRE_ROUTING,
-+ .priority = NF_IP_PRI_LAST-1,
-+ },
- /* After packet filtering, change source */
- {
- .hook = iptable_nat_ipv4_fn,
-diff --git a/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c b/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c
-index 0c366aad89cb..ae703d904727 100644
---- a/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c
-+++ b/net/ipv4/netfilter/nf_nat_masquerade_ipv4.c
-@@ -31,8 +31,8 @@ nf_nat_masquerade_ipv4(struct sk_buff *skb, unsigned int hooknum,
- struct nf_conn_nat *nat;
- enum ip_conntrack_info ctinfo;
- struct nf_nat_range newrange;
-- const struct rtable *rt;
-- __be32 newsrc, nh;
-+ struct rtable *rt;
-+ __be32 newsrc;
-
- WARN_ON(hooknum != NF_INET_POST_ROUTING);
-
-@@ -47,12 +47,23 @@ nf_nat_masquerade_ipv4(struct sk_buff *skb, unsigned int hooknum,
- if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip == 0)
- return NF_ACCEPT;
-
-- rt = skb_rtable(skb);
-- nh = rt_nexthop(rt, ip_hdr(skb)->daddr);
-- newsrc = inet_select_addr(out, nh, RT_SCOPE_UNIVERSE);
-- if (!newsrc) {
-- pr_info("%s ate my IP address\n", out->name);
-- return NF_DROP;
-+ {
-+ struct flowi4 fl4 = { .flowi4_tos = RT_TOS(ip_hdr(skb)->tos),
-+ .flowi4_mark = skb->mark,
-+ .flowi4_oif = out->ifindex,
-+ .daddr = ip_hdr(skb)->daddr,
-+ .fl4_gw = skb_rtable(skb)->rt_gateway };
-+ rt = ip_route_output_key(dev_net(out), &fl4);
-+ if (IS_ERR(rt)) {
-+ /* Funky routing can do this. */
-+ if (net_ratelimit())
-+ pr_info("%s:"
-+ " No route: Rusty's brain broke!\n",
-+ out->name);
-+ return NF_DROP;
-+ }
-+ newsrc = fl4.saddr;
-+ ip_rt_put(rt);
- }
-
- nat = nf_ct_nat_ext_add(ct);
-diff --git a/net/ipv4/route.c b/net/ipv4/route.c
-index df1c04d75f93..bdc2ee6fc8cf 100644
---- a/net/ipv4/route.c
-+++ b/net/ipv4/route.c
-@@ -1604,7 +1604,7 @@ int ip_mc_validate_source(struct sk_buff *skb, __be32 daddr, __be32 saddr,
- return -EINVAL;
- } else {
- err = fib_validate_source(skb, saddr, 0, tos, 0, dev,
-- in_dev, itag);
-+ in_dev, itag, 1);
- if (err < 0)
- return err;
- }
-@@ -1692,7 +1692,7 @@ static void set_lwt_redirect(struct rtable *rth)
- static int __mkroute_input(struct sk_buff *skb,
- const struct fib_result *res,
- struct in_device *in_dev,
-- __be32 daddr, __be32 saddr, u32 tos)
-+ __be32 daddr, __be32 saddr, u32 tos, __be32 lsrc)
- {
- struct fib_nh_exception *fnhe;
- struct rtable *rth;
-@@ -1709,7 +1709,7 @@ static int __mkroute_input(struct sk_buff *skb,
- }
-
- err = fib_validate_source(skb, saddr, daddr, tos, FIB_RES_OIF(*res),
-- in_dev->dev, in_dev, &itag);
-+ in_dev->dev, in_dev, &itag, 0);
- if (err < 0) {
- ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr,
- saddr);
-@@ -1719,7 +1719,7 @@ static int __mkroute_input(struct sk_buff *skb,
-
- do_cache = res->fi && !itag;
- if (out_dev == in_dev && err && IN_DEV_TX_REDIRECTS(out_dev) &&
-- skb->protocol == htons(ETH_P_IP) &&
-+ skb->protocol == htons(ETH_P_IP) && !lsrc &&
- (IN_DEV_SHARED_MEDIA(out_dev) ||
- inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res))))
- IPCB(skb)->flags |= IPSKB_DOREDIRECT;
-@@ -1874,9 +1874,11 @@ EXPORT_SYMBOL_GPL(fib_multipath_hash);
-
- static int ip_mkroute_input(struct sk_buff *skb,
- struct fib_result *res,
-+ const struct flowi4 *fl4,
- struct in_device *in_dev,
-- __be32 daddr, __be32 saddr, u32 tos)
-+ __be32 daddr, __be32 saddr, u32 tos, __be32 lsrc)
- {
-+ fib_select_default(fl4, res);
- #ifdef CONFIG_IP_ROUTE_MULTIPATH
- if (res->fi && res->fi->fib_nhs > 1) {
- int h = fib_multipath_hash(res->fi, NULL, skb);
-@@ -1886,7 +1888,7 @@ static int ip_mkroute_input(struct sk_buff *skb,
- #endif
-
- /* create a routing cache entry */
-- return __mkroute_input(skb, res, in_dev, daddr, saddr, tos);
-+ return __mkroute_input(skb, res, in_dev, daddr, saddr, tos, lsrc);
- }
-
- /*
-@@ -1901,7 +1903,7 @@ static int ip_mkroute_input(struct sk_buff *skb,
- */
-
- static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
-- u8 tos, struct net_device *dev,
-+ u8 tos, struct net_device *dev, __be32 lsrc,
- struct fib_result *res)
- {
- struct in_device *in_dev = __in_dev_get_rcu(dev);
-@@ -1958,19 +1960,28 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
- goto martian_source;
- }
-
-+ if (lsrc) {
-+ if (ipv4_is_multicast(lsrc) || ipv4_is_lbcast(lsrc) ||
-+ ipv4_is_zeronet(lsrc) || ipv4_is_loopback(lsrc))
-+ goto martian_source;
-+ }
-+
- /*
- * Now we are ready to route packet.
- */
- fl4.flowi4_oif = 0;
-- fl4.flowi4_iif = dev->ifindex;
-+ fl4.flowi4_iif = lsrc ? LOOPBACK_IFINDEX : dev->ifindex;
- fl4.flowi4_mark = skb->mark;
- fl4.flowi4_tos = tos;
- fl4.flowi4_scope = RT_SCOPE_UNIVERSE;
- fl4.flowi4_flags = 0;
- fl4.daddr = daddr;
-- fl4.saddr = saddr;
-+ fl4.saddr = lsrc? : saddr;
- fl4.flowi4_uid = sock_net_uid(net, NULL);
-+ fl4.fl4_gw = 0;
- err = fib_lookup(net, &fl4, res, 0);
-+ fl4.flowi4_iif = dev->ifindex;
-+ fl4.saddr = saddr;
- if (err != 0) {
- if (!IN_DEV_FORWARD(in_dev))
- err = -EHOSTUNREACH;
-@@ -1982,7 +1993,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
-
- if (res->type == RTN_LOCAL) {
- err = fib_validate_source(skb, saddr, daddr, tos,
-- 0, dev, in_dev, &itag);
-+ 0, dev, in_dev, &itag, 1);
- if (err < 0)
- goto martian_source;
- goto local_input;
-@@ -1995,16 +2006,19 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
- if (res->type != RTN_UNICAST)
- goto martian_destination;
-
-- err = ip_mkroute_input(skb, res, in_dev, daddr, saddr, tos);
-+ err = ip_mkroute_input(skb, res, &fl4, in_dev, daddr, saddr, tos,
-+ lsrc);
- out: return err;
-
- brd_input:
- if (skb->protocol != htons(ETH_P_IP))
- goto e_inval;
-+ if (lsrc)
-+ goto e_inval;
-
- if (!ipv4_is_zeronet(saddr)) {
- err = fib_validate_source(skb, saddr, 0, tos, 0, dev,
-- in_dev, &itag);
-+ in_dev, &itag, 1);
- if (err < 0)
- goto martian_source;
- }
-@@ -2110,9 +2124,26 @@ int ip_route_input_noref(struct sk_buff *skb, __be32 daddr, __be32 saddr,
- }
- EXPORT_SYMBOL(ip_route_input_noref);
-
-+int ip_route_input_lookup(struct sk_buff *skb, __be32 daddr, __be32 saddr,
-+ u8 tos, struct net_device *dev, __be32 lsrc)
-+{
-+ struct fib_result res;
-+ int err;
-+
-+ tos &= IPTOS_RT_MASK;
-+ rcu_read_lock();
-+ err = ip_route_input_common_rcu(skb, daddr, saddr, tos, dev, lsrc,
-+ &res);
-+ rcu_read_unlock();
-+
-+ return err;
-+}
-+EXPORT_SYMBOL(ip_route_input_lookup);
-+
- /* called with rcu_read_lock held */
--int ip_route_input_rcu(struct sk_buff *skb, __be32 daddr, __be32 saddr,
-- u8 tos, struct net_device *dev, struct fib_result *res)
-+int ip_route_input_common_rcu(struct sk_buff *skb, __be32 daddr, __be32 saddr,
-+ u8 tos, struct net_device *dev, __be32 lsrc,
-+ struct fib_result *res)
- {
- /* Multicast recognition logic is moved from route cache to here.
- The problem was that too many Ethernet cards have broken/missing
-@@ -2157,7 +2188,13 @@ int ip_route_input_rcu(struct sk_buff *skb, __be32 daddr, __be32 saddr,
- return err;
- }
-
-- return ip_route_input_slow(skb, daddr, saddr, tos, dev, res);
-+ return ip_route_input_slow(skb, daddr, saddr, tos, dev, lsrc, res);
-+}
-+
-+int ip_route_input_rcu(struct sk_buff *skb, __be32 daddr, __be32 saddr,
-+ u8 tos, struct net_device *dev, struct fib_result *res)
-+{
-+ return ip_route_input_common_rcu(skb, daddr, saddr, tos, dev, 0, res);
- }
-
- /* called with rcu_read_lock() */
-@@ -2411,6 +2448,7 @@ struct rtable *ip_route_output_key_hash_rcu(struct net *net, struct flowi4 *fl4,
- fl4->daddr = fl4->saddr = htonl(INADDR_LOOPBACK);
- dev_out = net->loopback_dev;
- fl4->flowi4_oif = LOOPBACK_IFINDEX;
-+ fl4->fl4_gw = 0;
- res->type = RTN_LOCAL;
- flags |= RTCF_LOCAL;
- goto make_route;
-@@ -2469,6 +2507,7 @@ struct rtable *ip_route_output_key_hash_rcu(struct net *net, struct flowi4 *fl4,
- orig_oif = FIB_RES_OIF(*res);
-
- fl4->flowi4_oif = dev_out->ifindex;
-+ fl4->fl4_gw = 0;
- flags |= RTCF_LOCAL;
- goto make_route;
- }
-diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
-index 6c38421e31f9..e71fece07178 100644
---- a/net/netfilter/nf_nat_core.c
-+++ b/net/netfilter/nf_nat_core.c
-@@ -798,6 +798,49 @@ static struct nf_ct_helper_expectfn follow_master_nat = {
- .expectfn = nf_nat_follow_master,
- };
-
-+unsigned int ip_nat_route_input(void *priv,
-+ struct sk_buff *skb,
-+ const struct nf_hook_state *state)
-+{
-+ struct iphdr *iph;
-+ struct nf_conn *conn;
-+ enum ip_conntrack_info ctinfo;
-+ enum ip_conntrack_dir dir;
-+ unsigned long statusbit;
-+ __be32 saddr;
-+
-+ if (!(conn = nf_ct_get(skb, &ctinfo)))
-+ return NF_ACCEPT;
-+
-+ if (!(conn->status & IPS_NAT_DONE_MASK))
-+ return NF_ACCEPT;
-+ dir = CTINFO2DIR(ctinfo);
-+ statusbit = IPS_SRC_NAT;
-+ if (dir == IP_CT_DIR_REPLY)
-+ statusbit ^= IPS_NAT_MASK;
-+ if (!(conn->status & statusbit))
-+ return NF_ACCEPT;
-+
-+ if (skb_dst(skb))
-+ return NF_ACCEPT;
-+
-+ if (skb->len < sizeof(struct iphdr))
-+ return NF_ACCEPT;
-+
-+ /* use daddr in other direction as masquerade address (lsrc) */
-+ iph = ip_hdr(skb);
-+ saddr = conn->tuplehash[!dir].tuple.dst.u3.ip;
-+ if (saddr == iph->saddr)
-+ return NF_ACCEPT;
-+
-+ if (ip_route_input_lookup(skb, iph->daddr, iph->saddr, iph->tos,
-+ skb->dev, saddr))
-+ return NF_DROP;
-+
-+ return NF_ACCEPT;
-+}
-+EXPORT_SYMBOL_GPL(ip_nat_route_input);
-+
- static int __init nf_nat_init(void)
- {
- int ret, i;
-diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
-index 7b7433a1a34c..db8cad6142b6 100644
---- a/security/selinux/nlmsgtab.c
-+++ b/security/selinux/nlmsgtab.c
-@@ -80,6 +80,9 @@ static const struct nlmsg_perm nlmsg_route_perms[] =
- { RTM_NEWSTATS, NETLINK_ROUTE_SOCKET__NLMSG_READ },
- { RTM_GETSTATS, NETLINK_ROUTE_SOCKET__NLMSG_READ },
- { RTM_NEWCACHEREPORT, NETLINK_ROUTE_SOCKET__NLMSG_READ },
-+ { RTM_NEWARPRULE, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
-+ { RTM_DELARPRULE, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
-+ { RTM_GETARPRULE, NETLINK_ROUTE_SOCKET__NLMSG_READ },
- };
-
- static const struct nlmsg_perm nlmsg_tcpdiag_perms[] =
-@@ -159,7 +162,7 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm)
- switch (sclass) {
- case SECCLASS_NETLINK_ROUTE_SOCKET:
- /* RTM_MAX always point to RTM_SETxxxx, ie RTM_NEWxxx + 3 */
-- BUILD_BUG_ON(RTM_MAX != (RTM_NEWCACHEREPORT + 3));
-+ BUILD_BUG_ON(RTM_MAX != (RTM_NEWARPRULE + 3));
- err = nlmsg_perm(nlmsg_type, perm, nlmsg_route_perms,
- sizeof(nlmsg_route_perms));
- break;
diff --git a/sys-kernel/boest-v4.16.18/0002-pool-2.6.25-tcp-timewait-20s.diff.patch b/sys-kernel/boest-v4.16.18/0002-pool-2.6.25-tcp-timewait-20s.diff.patch
deleted file mode 100644
index fbe56070..00000000
--- a/sys-kernel/boest-v4.16.18/0002-pool-2.6.25-tcp-timewait-20s.diff.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 9da34c060d616acd1dc55e99472965d9455021d4 Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Sun, 15 Feb 2009 14:51:33 +0100
-Subject: [PATCH 02/16] pool/2.6.25-tcp-timewait-20s.diff
-
-From http://linux.1wt.eu/alix/kernel-src/2.6.27-wt11/patches-2.6.27-wt11.tar.bz2
-
-Signed-off-by: Bertrand Jacquin <bertrand@jacquin.bzh>
----
- include/net/tcp.h | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/include/net/tcp.h b/include/net/tcp.h
-index e3fc667f9ac2..a5c87a06ba88 100644
---- a/include/net/tcp.h
-+++ b/include/net/tcp.h
-@@ -117,8 +117,8 @@ void tcp_time_wait(struct sock *sk, int state, int timeo);
- * initial RTO.
- */
-
--#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT
-- * state, about 60 seconds */
-+#define TCP_TIMEWAIT_LEN (20*HZ) /* how long to wait to destroy TIME-WAIT
-+ * state, about 20 seconds */
- #define TCP_FIN_TIMEOUT TCP_TIMEWAIT_LEN
- /* BSD style FIN_WAIT2 deadlock breaker.
- * It used to be 3min, new value is 60sec,
diff --git a/sys-kernel/boest-v4.16.18/0003-pool-2.6.25-disable-tcp-debug.diff.patch b/sys-kernel/boest-v4.16.18/0003-pool-2.6.25-disable-tcp-debug.diff.patch
deleted file mode 100644
index 1c98ad4e..00000000
--- a/sys-kernel/boest-v4.16.18/0003-pool-2.6.25-disable-tcp-debug.diff.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 31225eedd435a9074008cb01a3ab879666b9a272 Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Sun, 15 Feb 2009 14:51:33 +0100
-Subject: [PATCH 03/16] pool/2.6.25-disable-tcp-debug.diff
-
-From http://linux.1wt.eu/alix/kernel-src/2.6.27-wt11/patches-2.6.27-wt11.tar.bz2
-
-Signed-off-by: Bertrand Jacquin <bertrand@jacquin.bzh>
----
- include/net/tcp.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/include/net/tcp.h b/include/net/tcp.h
-index a5c87a06ba88..4f4c38957059 100644
---- a/include/net/tcp.h
-+++ b/include/net/tcp.h
-@@ -18,7 +18,7 @@
- #ifndef _TCP_H
- #define _TCP_H
-
--#define FASTRETRANS_DEBUG 1
-+#define FASTRETRANS_DEBUG 0
-
- #include <linux/list.h>
- #include <linux/tcp.h>
diff --git a/sys-kernel/boest-v4.16.18/0004-pool-2.6.25-disable-kbdrate-at-boot.diff.patch b/sys-kernel/boest-v4.16.18/0004-pool-2.6.25-disable-kbdrate-at-boot.diff.patch
deleted file mode 100644
index 656e1451..00000000
--- a/sys-kernel/boest-v4.16.18/0004-pool-2.6.25-disable-kbdrate-at-boot.diff.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From baec42e19131da6de057c9053d8cfae27f4f0b46 Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Sun, 15 Feb 2009 14:51:33 +0100
-Subject: [PATCH 04/16] pool/2.6.25-disable-kbdrate-at-boot.diff
-
-From http://linux.1wt.eu/alix/kernel-src/2.6.27-wt11/patches-2.6.27-wt11.tar.bz2
-
-Reviewed-by: Bertrand Jacquin <bertrand@jacquin.bzh>
-Signed-off-by: Bertrand Jacquin <bertrand@jacquin.bzh>
----
- arch/x86/boot/main.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/arch/x86/boot/main.c b/arch/x86/boot/main.c
-index 9bcea386db65..fd2d8e4e7d3a 100644
---- a/arch/x86/boot/main.c
-+++ b/arch/x86/boot/main.c
-@@ -64,6 +64,8 @@ static void copy_boot_params(void)
- */
- static void keyboard_init(void)
- {
-+/*This may take several seconds if the system has no kbd controller */
-+#ifdef CONFIG_INPUT_KEYBOARD
- struct biosregs ireg, oreg;
- initregs(&ireg);
-
-@@ -73,6 +75,7 @@ static void keyboard_init(void)
-
- ireg.ax = 0x0305; /* Set keyboard repeat rate */
- intcall(0x16, &ireg, NULL);
-+#endif
- }
-
- /*
diff --git a/sys-kernel/boest-v4.16.18/0005-x86-pci-add-support-for-pci-rev-net.patch b/sys-kernel/boest-v4.16.18/0005-x86-pci-add-support-for-pci-rev-net.patch
deleted file mode 100644
index 41697dad..00000000
--- a/sys-kernel/boest-v4.16.18/0005-x86-pci-add-support-for-pci-rev-net.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From d3f184428d66847162eade69b43b0cdbbcb6d415 Mon Sep 17 00:00:00 2001
-From: Willy Tarreau <w@1wt.eu>
-Date: Wed, 2 Feb 2011 12:40:44 +0100
-Subject: [PATCH 05/16] x86/pci: add support for pci=rev-net
-
-Scan network devices in the opposite order on each bus if pci=rev-net is found.
-
-Reviewed-by: Bertrand Jacquin <bertrand@jacquin.bzh>
-Signed-off-by: Bertrand Jacquin <bertrand@jacquin.bzh>
----
- arch/x86/include/asm/pci_x86.h | 1 +
- arch/x86/pci/common.c | 5 +++++
- drivers/pci/probe.c | 7 ++++++-
- 3 files changed, 12 insertions(+), 1 deletion(-)
-
-diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
-index eb66fa9cd0fc..5efc530a2edd 100644
---- a/arch/x86/include/asm/pci_x86.h
-+++ b/arch/x86/include/asm/pci_x86.h
-@@ -39,6 +39,7 @@ do { \
- #define PCI_ROOT_NO_CRS 0x100000
- #define PCI_NOASSIGN_BARS 0x200000
- #define PCI_BIG_ROOT_WINDOW 0x400000
-+#define PCI_REV_NETWORK 0x800000
-
- extern unsigned int pci_probe;
- extern unsigned long pirq_table_addr;
-diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
-index 563049c483a1..ca7de5f27a7c 100644
---- a/arch/x86/pci/common.c
-+++ b/arch/x86/pci/common.c
-@@ -19,6 +19,8 @@
- #include <asm/pci_x86.h>
- #include <asm/setup.h>
-
-+extern int pci_reverse_net;
-+
- unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
- PCI_PROBE_MMCONF;
-
-@@ -605,6 +607,9 @@ char *__init pcibios_setup(char *str)
- } else if (!strcmp(str, "routeirq")) {
- pci_routeirq = 1;
- return NULL;
-+ } else if (!strcmp(str, "rev-net")) {
-+ pci_reverse_net = 1;
-+ return NULL;
- } else if (!strcmp(str, "skip_isa_align")) {
- pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
- return NULL;
-diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
-index ef5377438a1e..8192a875e0f5 100644
---- a/drivers/pci/probe.c
-+++ b/drivers/pci/probe.c
-@@ -86,6 +86,8 @@ int no_pci_devices(void)
- }
- EXPORT_SYMBOL(no_pci_devices);
-
-+int pci_reverse_net;
-+
- /*
- * PCI Bus Class
- */
-@@ -942,7 +944,10 @@ struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev,
- child = pci_alloc_child_bus(parent, dev, busnr);
- if (child) {
- down_write(&pci_bus_sem);
-- list_add_tail(&child->node, &parent->children);
-+ if (pci_reverse_net && (dev->class >> 8) == PCI_CLASS_NETWORK_ETHERNET)
-+ list_add(&child->node, &parent->children);
-+ else
-+ list_add_tail(&child->node, &parent->children);
- up_write(&pci_bus_sem);
- }
- return child;
diff --git a/sys-kernel/boest-v4.16.18/0006-Disable-CONFIG_PROCESSOR_SELECT-printk-s.patch b/sys-kernel/boest-v4.16.18/0006-Disable-CONFIG_PROCESSOR_SELECT-printk-s.patch
deleted file mode 100644
index ca403c27..00000000
--- a/sys-kernel/boest-v4.16.18/0006-Disable-CONFIG_PROCESSOR_SELECT-printk-s.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 065b7ede577161a99101475e13fb99d7344b3bf2 Mon Sep 17 00:00:00 2001
-From: Bertrand Jacquin <bertrand@jacquin.bzh>
-Date: Wed, 9 Jan 2013 00:28:28 +0100
-Subject: [PATCH 06/16] Disable CONFIG_PROCESSOR_SELECT printk()'s
-
-Signed-off-by: Bertrand Jacquin <bertrand@jacquin.bzh>
----
- arch/x86/kernel/cpu/common.c | 17 -----------------
- 1 file changed, 17 deletions(-)
-
-diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
-index 5f74f94244e1..e2810387e54e 100644
---- a/arch/x86/kernel/cpu/common.c
-+++ b/arch/x86/kernel/cpu/common.c
-@@ -1049,10 +1049,6 @@ void __init early_cpu_init(void)
- const struct cpu_dev *const *cdev;
- int count = 0;
-
--#ifdef CONFIG_PROCESSOR_SELECT
-- pr_info("KERNEL supported cpus:\n");
--#endif
--
- for (cdev = __x86_cpu_dev_start; cdev < __x86_cpu_dev_end; cdev++) {
- const struct cpu_dev *cpudev = *cdev;
-
-@@ -1060,19 +1056,6 @@ void __init early_cpu_init(void)
- break;
- cpu_devs[count] = cpudev;
- count++;
--
--#ifdef CONFIG_PROCESSOR_SELECT
-- {
-- unsigned int j;
--
-- for (j = 0; j < 2; j++) {
-- if (!cpudev->c_ident[j])
-- continue;
-- pr_info(" %s %s\n", cpudev->c_vendor,
-- cpudev->c_ident[j]);
-- }
-- }
--#endif
- }
- early_identify_cpu(&boot_cpu_data);
- }
diff --git a/sys-kernel/boest-v4.16.18/0007-This-patch-adds-support-for-a-restricted-user-contro.patch b/sys-kernel/boest-v4.16.18/0007-This-patch-adds-support-for-a-restricted-user-contro.patch
deleted file mode 100644
index deb3bdf4..00000000
--- a/sys-kernel/boest-v4.16.18/0007-This-patch-adds-support-for-a-restricted-user-contro.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From 4b44ffa9cd246450df6582d5b057cccdaca63c1b Mon Sep 17 00:00:00 2001
-From: "Anthony G. Basile" <blueness@gentoo.org>
-Date: Mon, 12 Feb 2018 15:44:07 -0500
-Subject: [PATCH 07/16] This patch adds support for a restricted
- user-controlled namespace on tmpfs filesystem used to house PaX flags. The
- namespace must be of the form user.pax.* and its value cannot exceed a size
- of 8 bytes.
-
-This is needed even on all Gentoo systems so that XATTR_PAX flags
-are preserved for users who might build packages using portage on
-a tmpfs system with a non-hardened kernel and then switch to a
-hardened kernel with XATTR_PAX enabled.
-
-The namespace is added to any user with Extended Attribute support
-enabled for tmpfs. Users who do not enable xattrs will not have
-the XATTR_PAX flags preserved.
----
- include/uapi/linux/xattr.h | 4 ++++
- mm/shmem.c | 15 +++++++++++++++
- 2 files changed, 19 insertions(+)
-
-diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h
-index c1395b5bd432..bac6d48eca8e 100644
---- a/include/uapi/linux/xattr.h
-+++ b/include/uapi/linux/xattr.h
-@@ -77,5 +77,9 @@
- #define XATTR_POSIX_ACL_DEFAULT "posix_acl_default"
- #define XATTR_NAME_POSIX_ACL_DEFAULT XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_DEFAULT
-
-+/* User namespace */
-+#define XATTR_PAX_PREFIX XATTR_USER_PREFIX "pax."
-+#define XATTR_PAX_FLAGS_SUFFIX "flags"
-+#define XATTR_NAME_PAX_FLAGS XATTR_PAX_PREFIX XATTR_PAX_FLAGS_SUFFIX
-
- #endif /* _UAPI_LINUX_XATTR_H */
-diff --git a/mm/shmem.c b/mm/shmem.c
-index b85919243399..57d17d8f7a33 100644
---- a/mm/shmem.c
-+++ b/mm/shmem.c
-@@ -3366,6 +3366,14 @@ static int shmem_xattr_handler_set(const struct xattr_handler *handler,
- struct shmem_inode_info *info = SHMEM_I(inode);
-
- name = xattr_full_name(handler, name);
-+
-+ if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
-+ if (strcmp(name, XATTR_NAME_PAX_FLAGS))
-+ return -EOPNOTSUPP;
-+ if (size > 8)
-+ return -EINVAL;
-+ }
-+
- return simple_xattr_set(&info->xattrs, name, value, size, flags);
- }
-
-@@ -3381,6 +3389,12 @@ static const struct xattr_handler shmem_trusted_xattr_handler = {
- .set = shmem_xattr_handler_set,
- };
-
-+static const struct xattr_handler shmem_user_xattr_handler = {
-+ .prefix = XATTR_USER_PREFIX,
-+ .get = shmem_xattr_handler_get,
-+ .set = shmem_xattr_handler_set,
-+};
-+
- static const struct xattr_handler *shmem_xattr_handlers[] = {
- #ifdef CONFIG_TMPFS_POSIX_ACL
- &posix_acl_access_xattr_handler,
-@@ -3388,6 +3402,7 @@ static const struct xattr_handler *shmem_xattr_handlers[] = {
- #endif
- &shmem_security_xattr_handler,
- &shmem_trusted_xattr_handler,
-+ &shmem_user_xattr_handler,
- NULL
- };
-
diff --git a/sys-kernel/boest-v4.16.18/0008-fs-Enable-link-security-restrictions-by-default.patch b/sys-kernel/boest-v4.16.18/0008-fs-Enable-link-security-restrictions-by-default.patch
deleted file mode 100644
index 6135e458..00000000
--- a/sys-kernel/boest-v4.16.18/0008-fs-Enable-link-security-restrictions-by-default.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From aab5abf3f2d2c26fb0731e71090e5df23e45b309 Mon Sep 17 00:00:00 2001
-From: Ben Hutchings <ben@decadent.org.uk>
-Date: Fri, 2 Nov 2012 05:32:06 +0000
-Subject: [PATCH 08/16] fs: Enable link security restrictions by default
-
-This reverts commit 561ec64ae67ef25cac8d72bb9c4bfc955edfd415
-('VFS: don't do protected {sym,hard}links by default').
----
- fs/namei.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/fs/namei.c b/fs/namei.c
-index b61d6aa9279d..255c2dc36189 100644
---- a/fs/namei.c
-+++ b/fs/namei.c
-@@ -883,8 +883,8 @@ static inline void put_link(struct nameidata *nd)
- path_put(&last->link);
- }
-
--int sysctl_protected_symlinks __read_mostly = 0;
--int sysctl_protected_hardlinks __read_mostly = 0;
-+int sysctl_protected_symlinks __read_mostly = 1;
-+int sysctl_protected_hardlinks __read_mostly = 1;
-
- /**
- * may_follow_link - Check symlink following for unsafe situations
diff --git a/sys-kernel/boest-v4.16.18/0009-UBUNTU-SAUCE-PCI-Workaround-to-enable-poweroff-on-Ma.patch b/sys-kernel/boest-v4.16.18/0009-UBUNTU-SAUCE-PCI-Workaround-to-enable-poweroff-on-Ma.patch
deleted file mode 100644
index 9a9ef61f..00000000
--- a/sys-kernel/boest-v4.16.18/0009-UBUNTU-SAUCE-PCI-Workaround-to-enable-poweroff-on-Ma.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From a7bc41c6ea6eb33d84cb6b25846504a0c5660c0d Mon Sep 17 00:00:00 2001
-From: Chen Yu <yu.c.chen@intel.com>
-Date: Fri, 19 Aug 2016 10:25:57 -0700
-Subject: [PATCH 09/16] UBUNTU: SAUCE: PCI: Workaround to enable poweroff on
- Mac Pro 11
-
-BugLink: http://bugs.launchpad.net/bugs/1587714
-
-People reported that they can not do a poweroff nor a
-suspend to ram on their Mac Pro 11. After some investigations
-it was found that, once the PCI bridge 0000:00:1c.0 reassigns its
-mm windows to ([mem 0x7fa00000-0x7fbfffff] and
-[mem 0x7fc00000-0x7fdfffff 64bit pref]), the region of ACPI
-io resource 0x1804 becomes unaccessible immediately, where the
-ACPI Sleep register is located, as a result neither poweroff(S5)
-nor suspend to ram(S3) works.
-
-As suggested by Bjorn, further testing shows that, there is an
-unreported device may be (using) conflict with above aperture,
-which brings unpredictable result such as the failure of accessing
-the io port, which blocks the poweroff(S5). Besides if we reassign
-the memory aperture to the other place, the poweroff works again.
-
-As we do not find any resource declared in _CRS which contain above
-memory aperture, and Mac OS does not use this pci bridge neither, we
-choose a simple workaround to clear the hotplug flag(suggested by
-Yinghai Lu), thus do not allocate any resource for this pci bridge,
-and thereby no conflict anymore.
-
-Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=103211
-Cc: Bjorn Helgaas <bhelgaas@google.com>
-Cc: Rafael J. Wysocki <rafael@kernel.org>
-Cc: Lukas Wunner <lukas@wunner.de>
-Signed-off-by: Chen Yu <yu.c.chen@intel.com>
-Reference: https://patchwork.kernel.org/patch/9289777/
-Signed-off-by: Kamal Mostafa <kamal@canonical.com>
-Acked-by: Brad Figg <brad.figg@canonical.com>
-Acked-by: Stefan Bader <stefan.bader@canonical.com>
-Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
----
- drivers/pci/quirks.c | 20 ++++++++++++++++++++
- 1 file changed, 20 insertions(+)
-
-diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
-index 88598dbdc1b0..20c9b7130ce2 100644
---- a/drivers/pci/quirks.c
-+++ b/drivers/pci/quirks.c
-@@ -2847,6 +2847,26 @@ static void quirk_hotplug_bridge(struct pci_dev *dev)
- DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_HINT, 0x0020, quirk_hotplug_bridge);
-
- /*
-+ * Apple: Avoid programming the memory/io aperture of 00:1c.0
-+ *
-+ * BIOS does not declare any resource for 00:1c.0, but with
-+ * hotplug flag set, thus the OS allocates:
-+ * [mem 0x7fa00000 - 0x7fbfffff]
-+ * [mem 0x7fc00000-0x7fdfffff 64bit pref]
-+ * which is conflict with an unreported device, which
-+ * causes unpredictable result such as accessing io port.
-+ * So clear the hotplug flag to work around it.
-+ */
-+static void quirk_apple_mbp_poweroff(struct pci_dev *dev)
-+{
-+ if (dmi_match(DMI_PRODUCT_NAME, "MacBookPro11,4") ||
-+ dmi_match(DMI_PRODUCT_NAME, "MacBookPro11,5"))
-+ dev->is_hotplug_bridge = 0;
-+}
-+
-+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x8c10, quirk_apple_mbp_poweroff);
-+
-+/*
- * This is a quirk for the Ricoh MMC controller found as a part of
- * some mulifunction chips.
-
diff --git a/sys-kernel/boest-v4.16.18/0010-usb-storage-Disable-UAS-on-JMicron-SATA-enclosure.patch b/sys-kernel/boest-v4.16.18/0010-usb-storage-Disable-UAS-on-JMicron-SATA-enclosure.patch
deleted file mode 100644
index dd30f554..00000000
--- a/sys-kernel/boest-v4.16.18/0010-usb-storage-Disable-UAS-on-JMicron-SATA-enclosure.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 688bde208e8f46e1ca934d4b2050f04bb003e692 Mon Sep 17 00:00:00 2001
-From: Laura Abbott <labbott@fedoraproject.org>
-Date: Tue, 8 Sep 2015 09:53:38 -0700
-Subject: [PATCH 10/16] usb-storage: Disable UAS on JMicron SATA enclosure
-
-Steve Ellis reported incorrect block sizes and alignement
-offsets with a SATA enclosure. Adding a quirk to disable
-UAS fixes the problems.
-
-Reported-by: Steven Ellis <sellis@redhat.com>
-Signed-off-by: Laura Abbott <labbott@fedoraproject.org>
----
- drivers/usb/storage/unusual_uas.h | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h
-index d0bdebd87ce3..1b23741036ee 100644
---- a/drivers/usb/storage/unusual_uas.h
-+++ b/drivers/usb/storage/unusual_uas.h
-@@ -87,12 +87,15 @@ UNUSUAL_DEV(0x2537, 0x1068, 0x0000, 0x9999,
- USB_SC_DEVICE, USB_PR_DEVICE, NULL,
- US_FL_IGNORE_UAS),
-
--/* Reported-by: Takeo Nakayama <javhera@gmx.com> */
-+/*
-+ * Initially Reported-by: Takeo Nakayama <javhera@gmx.com>
-+ * UAS Ignore Reported by Steven Ellis <sellis@redhat.com>
-+ */
- UNUSUAL_DEV(0x357d, 0x7788, 0x0000, 0x9999,
- "JMicron",
- "JMS566",
- USB_SC_DEVICE, USB_PR_DEVICE, NULL,
-- US_FL_NO_REPORT_OPCODES),
-+ US_FL_NO_REPORT_OPCODES | US_FL_IGNORE_UAS),
-
- /* Reported-by: Hans de Goede <hdegoede@redhat.com> */
- UNUSUAL_DEV(0x4971, 0x1012, 0x0000, 0x9999,
diff --git a/sys-kernel/boest-v4.16.18/0011-4.16-2600_enable-key-swapping-for-apple-mac.patch.patch b/sys-kernel/boest-v4.16.18/0011-4.16-2600_enable-key-swapping-for-apple-mac.patch.patch
deleted file mode 100644
index 20bf9709..00000000
--- a/sys-kernel/boest-v4.16.18/0011-4.16-2600_enable-key-swapping-for-apple-mac.patch.patch
+++ /dev/null
@@ -1,125 +0,0 @@
-From 941455a8270c4ec8711423b0fb83f15ae05c9c8a Mon Sep 17 00:00:00 2001
-From: Mike Pagano <mpagano@gentoo.org>
-Date: Mon, 12 Feb 2018 15:44:07 -0500
-Subject: [PATCH 11/16] 4.16:2600_enable-key-swapping-for-apple-mac.patch
-
----
- drivers/hid/hid-apple.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++--
- 1 file changed, 74 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
-index 25b7bd56ae11..d043ff014275 100644
---- a/drivers/hid/hid-apple.c
-+++ b/drivers/hid/hid-apple.c
-@@ -54,6 +54,22 @@ MODULE_PARM_DESC(swap_opt_cmd, "Swap the Option (\"Alt\") and Command (\"Flag\")
- "(For people who want to keep Windows PC keyboard muscle memory. "
- "[0] = as-is, Mac layout. 1 = swapped, Windows layout.)");
-
-+static unsigned int swap_fn_leftctrl;
-+module_param(swap_fn_leftctrl, uint, 0644);
-+MODULE_PARM_DESC(swap_fn_leftctrl, "Swap the Fn and left Control keys. "
-+ "(For people who want to keep PC keyboard muscle memory. "
-+ "[0] = as-is, Mac layout, 1 = swapped, PC layout)");
-+
-+static unsigned int rightalt_as_rightctrl;
-+module_param(rightalt_as_rightctrl, uint, 0644);
-+MODULE_PARM_DESC(rightalt_as_rightctrl, "Use the right Alt key as a right Ctrl key. "
-+ "[0] = as-is, Mac layout. 1 = Right Alt is right Ctrl");
-+
-+static unsigned int ejectcd_as_delete;
-+module_param(ejectcd_as_delete, uint, 0644);
-+MODULE_PARM_DESC(ejectcd_as_delete, "Use Eject-CD key as Delete key. "
-+ "([0] = disabled, 1 = enabled)");
-+
- struct apple_sc {
- unsigned long quirks;
- unsigned int fn_on;
-@@ -166,6 +182,21 @@ static const struct apple_key_translation swapped_option_cmd_keys[] = {
- { }
- };
-
-+static const struct apple_key_translation swapped_fn_leftctrl_keys[] = {
-+ { KEY_FN, KEY_LEFTCTRL },
-+ { }
-+};
-+
-+static const struct apple_key_translation rightalt_as_rightctrl_keys[] = {
-+ { KEY_RIGHTALT, KEY_RIGHTCTRL },
-+ { }
-+};
-+
-+static const struct apple_key_translation ejectcd_as_delete_keys[] = {
-+ { KEY_EJECTCD, KEY_DELETE },
-+ { }
-+};
-+
- static const struct apple_key_translation *apple_find_translation(
- const struct apple_key_translation *table, u16 from)
- {
-@@ -185,9 +216,11 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
- struct apple_sc *asc = hid_get_drvdata(hid);
- const struct apple_key_translation *trans, *table;
-
-- if (usage->code == KEY_FN) {
-+ u16 fn_keycode = (swap_fn_leftctrl) ? (KEY_LEFTCTRL) : (KEY_FN);
-+
-+ if (usage->code == fn_keycode) {
- asc->fn_on = !!value;
-- input_event(input, usage->type, usage->code, value);
-+ input_event(input, usage->type, KEY_FN, value);
- return 1;
- }
-
-@@ -266,6 +299,30 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
- }
- }
-
-+ if (swap_fn_leftctrl) {
-+ trans = apple_find_translation(swapped_fn_leftctrl_keys, usage->code);
-+ if (trans) {
-+ input_event(input, usage->type, trans->to, value);
-+ return 1;
-+ }
-+ }
-+
-+ if (ejectcd_as_delete) {
-+ trans = apple_find_translation(ejectcd_as_delete_keys, usage->code);
-+ if (trans) {
-+ input_event(input, usage->type, trans->to, value);
-+ return 1;
-+ }
-+ }
-+
-+ if (rightalt_as_rightctrl) {
-+ trans = apple_find_translation(rightalt_as_rightctrl_keys, usage->code);
-+ if (trans) {
-+ input_event(input, usage->type, trans->to, value);
-+ return 1;
-+ }
-+ }
-+
- return 0;
- }
-
-@@ -329,6 +386,21 @@ static void apple_setup_input(struct input_dev *input)
-
- for (trans = apple_iso_keyboard; trans->from; trans++)
- set_bit(trans->to, input->keybit);
-+
-+ if (swap_fn_leftctrl) {
-+ for (trans = swapped_fn_leftctrl_keys; trans->from; trans++)
-+ set_bit(trans->to, input->keybit);
-+ }
-+
-+ if (ejectcd_as_delete) {
-+ for (trans = ejectcd_as_delete_keys; trans->from; trans++)
-+ set_bit(trans->to, input->keybit);
-+ }
-+
-+ if (rightalt_as_rightctrl) {
-+ for (trans = rightalt_as_rightctrl_keys; trans->from; trans++)
-+ set_bit(trans->to, input->keybit);
-+ }
- }
-
- static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,
diff --git a/sys-kernel/boest-v4.16.18/0012-4.16-2900_dev-root-proc-mount-fix.patch.patch b/sys-kernel/boest-v4.16.18/0012-4.16-2900_dev-root-proc-mount-fix.patch.patch
deleted file mode 100644
index 93465556..00000000
--- a/sys-kernel/boest-v4.16.18/0012-4.16-2900_dev-root-proc-mount-fix.patch.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 34c647610ec392d73f6349cdd6d9cbe562edb14d Mon Sep 17 00:00:00 2001
-From: Mike Pagano <mpagano@gentoo.org>
-Date: Mon, 12 Feb 2018 15:44:07 -0500
-Subject: [PATCH 12/16] 4.16:2900_dev-root-proc-mount-fix.patch
-
----
- init/do_mounts.c | 22 ++++++++++++++++------
- 1 file changed, 16 insertions(+), 6 deletions(-)
-
-diff --git a/init/do_mounts.c b/init/do_mounts.c
-index 7cf4f6dafd5f..96a0dfcf0804 100644
---- a/init/do_mounts.c
-+++ b/init/do_mounts.c
-@@ -489,7 +489,11 @@ void __init change_floppy(char *fmt, ...)
- va_start(args, fmt);
- vsprintf(buf, fmt, args);
- va_end(args);
-- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
-+ if (saved_root_name[0])
-+ fd = sys_open(saved_root_name, O_RDWR | O_NDELAY, 0);
-+ else
-+ fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
-+
- if (fd >= 0) {
- sys_ioctl(fd, FDEJECT, 0);
- sys_close(fd);
-@@ -533,11 +537,17 @@ void __init mount_root(void)
- #endif
- #ifdef CONFIG_BLOCK
- {
-- int err = create_dev("/dev/root", ROOT_DEV);
--
-- if (err < 0)
-- pr_emerg("Failed to create /dev/root: %d\n", err);
-- mount_block_root("/dev/root", root_mountflags);
-+ if (saved_root_name[0] == '/') {
-+ int err = create_dev(saved_root_name, ROOT_DEV);
-+ if (err < 0)
-+ pr_emerg("Failed to create %s: %d\n", saved_root_name, err);
-+ mount_block_root(saved_root_name, root_mountflags);
-+ } else {
-+ int err = create_dev("/dev/root", ROOT_DEV);
-+ if (err < 0)
-+ pr_emerg("Failed to create /dev/root: %d\n", err);
-+ mount_block_root("/dev/root", root_mountflags);
-+ }
- }
- #endif
- }
diff --git a/sys-kernel/boest-v4.16.18/0013-4.16-4200_fbcondecor.patch.patch b/sys-kernel/boest-v4.16.18/0013-4.16-4200_fbcondecor.patch.patch
deleted file mode 100644
index ed134070..00000000
--- a/sys-kernel/boest-v4.16.18/0013-4.16-4200_fbcondecor.patch.patch
+++ /dev/null
@@ -1,2119 +0,0 @@
-From d80da7e46f845bc44c715be23fea7ac373a47f00 Mon Sep 17 00:00:00 2001
-From: Mike Pagano <mpagano@gentoo.org>
-Date: Mon, 12 Feb 2018 15:44:07 -0500
-Subject: [PATCH 13/16] 4.16:4200_fbcondecor.patch
-
----
- Documentation/fb/00-INDEX | 2 +
- Documentation/fb/fbcondecor.txt | 206 ++++++++++++++
- drivers/Makefile | 9 +-
- drivers/video/console/Kconfig | 13 +
- drivers/video/console/Makefile | 1 +
- drivers/video/console/cfbcondecor.c | 472 +++++++++++++++++++++++++++++++
- drivers/video/console/fbcondecor.c | 549 ++++++++++++++++++++++++++++++++++++
- drivers/video/console/fbcondecor.h | 77 +++++
- drivers/video/fbdev/Kconfig | 1 -
- drivers/video/fbdev/core/bitblit.c | 20 +-
- drivers/video/fbdev/core/fbcmap.c | 9 +-
- drivers/video/fbdev/core/fbcon.c | 171 +++++++++--
- drivers/video/fbdev/core/fbmem.c | 9 -
- include/linux/console_decor.h | 46 +++
- include/linux/console_struct.h | 3 +
- include/linux/fb.h | 31 ++
- include/uapi/linux/fb.h | 59 ++++
- kernel/sysctl.c | 13 +
- 18 files changed, 1647 insertions(+), 44 deletions(-)
-
-diff --git a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX
-index fe85e7c5907a..22309308ba56 100644
---- a/Documentation/fb/00-INDEX
-+++ b/Documentation/fb/00-INDEX
-@@ -23,6 +23,8 @@ ep93xx-fb.txt
- - info on the driver for EP93xx LCD controller.
- fbcon.txt
- - intro to and usage guide for the framebuffer console (fbcon).
-+fbcondecor.txt
-+ - info on the Framebuffer Console Decoration
- framebuffer.txt
- - introduction to frame buffer devices.
- gxfb.txt
-diff --git a/Documentation/fb/fbcondecor.txt b/Documentation/fb/fbcondecor.txt
-new file mode 100644
-index 000000000000..f074bba42eaf
---- /dev/null
-+++ b/Documentation/fb/fbcondecor.txt
-@@ -0,0 +1,206 @@
-+What is it?
-+-----------
-+
-+The framebuffer decorations are a kernel feature which allows displaying a
-+background picture on selected consoles.
-+
-+What do I need to get it to work?
-+---------------------------------
-+
-+To get fbcondecor up-and-running you will have to:
-+ 1) get a copy of splashutils [1] or a similar program
-+ 2) get some fbcondecor themes
-+ 3) build the kernel helper program
-+ 4) build your kernel with the FB_CON_DECOR option enabled.
-+
-+To get fbcondecor operational right after fbcon initialization is finished, you
-+will have to include a theme and the kernel helper into your initramfs image.
-+Please refer to splashutils documentation for instructions on how to do that.
-+
-+[1] The splashutils package can be downloaded from:
-+ http://github.com/alanhaggai/fbsplash
-+
-+The userspace helper
-+--------------------
-+
-+The userspace fbcondecor helper (by default: /sbin/fbcondecor_helper) is called by the
-+kernel whenever an important event occurs and the kernel needs some kind of
-+job to be carried out. Important events include console switches and video
-+mode switches (the kernel requests background images and configuration
-+parameters for the current console). The fbcondecor helper must be accessible at
-+all times. If it's not, fbcondecor will be switched off automatically.
-+
-+It's possible to set path to the fbcondecor helper by writing it to
-+/proc/sys/kernel/fbcondecor.
-+
-+*****************************************************************************
-+
-+The information below is mostly technical stuff. There's probably no need to
-+read it unless you plan to develop a userspace helper.
-+
-+The fbcondecor protocol
-+-----------------------
-+
-+The fbcondecor protocol defines a communication interface between the kernel and
-+the userspace fbcondecor helper.
-+
-+The kernel side is responsible for:
-+
-+ * rendering console text, using an image as a background (instead of a
-+ standard solid color fbcon uses),
-+ * accepting commands from the user via ioctls on the fbcondecor device,
-+ * calling the userspace helper to set things up as soon as the fb subsystem
-+ is initialized.
-+
-+The userspace helper is responsible for everything else, including parsing
-+configuration files, decompressing the image files whenever the kernel needs
-+it, and communicating with the kernel if necessary.
-+
-+The fbcondecor protocol specifies how communication is done in both ways:
-+kernel->userspace and userspace->helper.
-+
-+Kernel -> Userspace
-+-------------------
-+
-+The kernel communicates with the userspace helper by calling it and specifying
-+the task to be done in a series of arguments.
-+
-+The arguments follow the pattern:
-+<fbcondecor protocol version> <command> <parameters>
-+
-+All commands defined in fbcondecor protocol v2 have the following parameters:
-+ virtual console
-+ framebuffer number
-+ theme
-+
-+Fbcondecor protocol v1 specified an additional 'fbcondecor mode' after the
-+framebuffer number. Fbcondecor protocol v1 is deprecated and should not be used.
-+
-+Fbcondecor protocol v2 specifies the following commands:
-+
-+getpic
-+------
-+ The kernel issues this command to request image data. It's up to the
-+ userspace helper to find a background image appropriate for the specified
-+ theme and the current resolution. The userspace helper should respond by
-+ issuing the FBIOCONDECOR_SETPIC ioctl.
-+
-+init
-+----
-+ The kernel issues this command after the fbcondecor device is created and
-+ the fbcondecor interface is initialized. Upon receiving 'init', the userspace
-+ helper should parse the kernel command line (/proc/cmdline) or otherwise
-+ decide whether fbcondecor is to be activated.
-+
-+ To activate fbcondecor on the first console the helper should issue the
-+ FBIOCONDECOR_SETCFG, FBIOCONDECOR_SETPIC and FBIOCONDECOR_SETSTATE commands,
-+ in the above-mentioned order.
-+
-+ When the userspace helper is called in an early phase of the boot process
-+ (right after the initialization of fbcon), no filesystems will be mounted.
-+ The helper program should mount sysfs and then create the appropriate
-+ framebuffer, fbcondecor and tty0 devices (if they don't already exist) to get
-+ current display settings and to be able to communicate with the kernel side.
-+ It should probably also mount the procfs to be able to parse the kernel
-+ command line parameters.
-+
-+ Note that the console sem is not held when the kernel calls fbcondecor_helper
-+ with the 'init' command. The fbcondecor helper should perform all ioctls with
-+ origin set to FBCON_DECOR_IO_ORIG_USER.
-+
-+modechange
-+----------
-+ The kernel issues this command on a mode change. The helper's response should
-+ be similar to the response to the 'init' command. Note that this time the
-+ console sem is held and all ioctls must be performed with origin set to
-+ FBCON_DECOR_IO_ORIG_KERNEL.
-+
-+
-+Userspace -> Kernel
-+-------------------
-+
-+Userspace programs can communicate with fbcondecor via ioctls on the
-+fbcondecor device. These ioctls are to be used by both the userspace helper
-+(called only by the kernel) and userspace configuration tools (run by the users).
-+
-+The fbcondecor helper should set the origin field to FBCON_DECOR_IO_ORIG_KERNEL
-+when doing the appropriate ioctls. All userspace configuration tools should
-+use FBCON_DECOR_IO_ORIG_USER. Failure to set the appropriate value in the origin
-+field when performing ioctls from the kernel helper will most likely result
-+in a console deadlock.
-+
-+FBCON_DECOR_IO_ORIG_KERNEL instructs fbcondecor not to try to acquire the console
-+semaphore. Not surprisingly, FBCON_DECOR_IO_ORIG_USER instructs it to acquire
-+the console sem.
-+
-+The framebuffer console decoration provides the following ioctls (all defined in
-+linux/fb.h):
-+
-+FBIOCONDECOR_SETPIC
-+description: loads a background picture for a virtual console
-+argument: struct fbcon_decor_iowrapper*; data: struct fb_image*
-+notes:
-+If called for consoles other than the current foreground one, the picture data
-+will be ignored.
-+
-+If the current virtual console is running in a 8-bpp mode, the cmap substruct
-+of fb_image has to be filled appropriately: start should be set to 16 (first
-+16 colors are reserved for fbcon), len to a value <= 240 and red, green and
-+blue should point to valid cmap data. The transp field is ingored. The fields
-+dx, dy, bg_color, fg_color in fb_image are ignored as well.
-+
-+FBIOCONDECOR_SETCFG
-+description: sets the fbcondecor config for a virtual console
-+argument: struct fbcon_decor_iowrapper*; data: struct vc_decor*
-+notes: The structure has to be filled with valid data.
-+
-+FBIOCONDECOR_GETCFG
-+description: gets the fbcondecor config for a virtual console
-+argument: struct fbcon_decor_iowrapper*; data: struct vc_decor*
-+
-+FBIOCONDECOR_SETSTATE
-+description: sets the fbcondecor state for a virtual console
-+argument: struct fbcon_decor_iowrapper*; data: unsigned int*
-+ values: 0 = disabled, 1 = enabled.
-+
-+FBIOCONDECOR_GETSTATE
-+description: gets the fbcondecor state for a virtual console
-+argument: struct fbcon_decor_iowrapper*; data: unsigned int*
-+ values: as in FBIOCONDECOR_SETSTATE
-+
-+Info on used structures:
-+
-+Definition of struct vc_decor can be found in linux/console_decor.h. It's
-+heavily commented. Note that the 'theme' field should point to a string
-+no longer than FBCON_DECOR_THEME_LEN. When FBIOCONDECOR_GETCFG call is
-+performed, the theme field should point to a char buffer of length
-+FBCON_DECOR_THEME_LEN.
-+
-+Definition of struct fbcon_decor_iowrapper can be found in linux/fb.h.
-+The fields in this struct have the following meaning:
-+
-+vc:
-+Virtual console number.
-+
-+origin:
-+Specifies if the ioctl is performed as a response to a kernel request. The
-+fbcondecor helper should set this field to FBCON_DECOR_IO_ORIG_KERNEL, userspace
-+programs should set it to FBCON_DECOR_IO_ORIG_USER. This field is necessary to
-+avoid console semaphore deadlocks.
-+
-+data:
-+Pointer to a data structure appropriate for the performed ioctl. Type of
-+the data struct is specified in the ioctls description.
-+
-+*****************************************************************************
-+
-+Credit
-+------
-+
-+Original 'bootsplash' project & implementation by:
-+ Volker Poplawski <volker@poplawski.de>, Stefan Reinauer <stepan@suse.de>,
-+ Steffen Winterfeldt <snwint@suse.de>, Michael Schroeder <mls@suse.de>,
-+ Ken Wimer <wimer@suse.de>.
-+
-+Fbcondecor, fbcondecor protocol design, current implementation & docs by:
-+ Michal Januszewski <michalj+fbcondecor@gmail.com>
-diff --git a/drivers/Makefile b/drivers/Makefile
-index 24cd47014657..3dd319d11823 100644
---- a/drivers/Makefile
-+++ b/drivers/Makefile
-@@ -20,6 +20,10 @@ obj-y += pci/
-
- obj-$(CONFIG_PARISC) += parisc/
- obj-$(CONFIG_RAPIDIO) += rapidio/
-+# tty/ comes before char/ so that the VT console is the boot-time
-+# default.
-+obj-y += tty/
-+obj-y += char/
- obj-y += video/
- obj-y += idle/
-
-@@ -50,11 +54,6 @@ obj-$(CONFIG_REGULATOR) += regulator/
- # reset controllers early, since gpu drivers might rely on them to initialize
- obj-$(CONFIG_RESET_CONTROLLER) += reset/
-
--# tty/ comes before char/ so that the VT console is the boot-time
--# default.
--obj-y += tty/
--obj-y += char/
--
- # iommu/ comes before gpu as gpu are using iommu controllers
- obj-$(CONFIG_IOMMU_SUPPORT) += iommu/
-
-diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
-index 7f1f1fbcef9e..8439b618dfc0 100644
---- a/drivers/video/console/Kconfig
-+++ b/drivers/video/console/Kconfig
-@@ -151,6 +151,19 @@ config FRAMEBUFFER_CONSOLE_ROTATION
- such that other users of the framebuffer will remain normally
- oriented.
-
-+config FB_CON_DECOR
-+ bool "Support for the Framebuffer Console Decorations"
-+ depends on FRAMEBUFFER_CONSOLE=y && !FB_TILEBLITTING
-+ default n
-+ ---help---
-+ This option enables support for framebuffer console decorations which
-+ makes it possible to display images in the background of the system
-+ consoles. Note that userspace utilities are necessary in order to take
-+ advantage of these features. Refer to Documentation/fb/fbcondecor.txt
-+ for more information.
-+
-+ If unsure, say N.
-+
- config STI_CONSOLE
- bool "STI text console"
- depends on PARISC
-diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
-index db07b784bd2c..3e369bd120b8 100644
---- a/drivers/video/console/Makefile
-+++ b/drivers/video/console/Makefile
-@@ -9,4 +9,5 @@ obj-$(CONFIG_STI_CONSOLE) += sticon.o sticore.o
- obj-$(CONFIG_VGA_CONSOLE) += vgacon.o
- obj-$(CONFIG_MDA_CONSOLE) += mdacon.o
-
-+obj-$(CONFIG_FB_CON_DECOR) += fbcondecor.o cfbcondecor.o
- obj-$(CONFIG_FB_STI) += sticore.o
-diff --git a/drivers/video/console/cfbcondecor.c b/drivers/video/console/cfbcondecor.c
-new file mode 100644
-index 000000000000..5ec87e23b69a
---- /dev/null
-+++ b/drivers/video/console/cfbcondecor.c
-@@ -0,0 +1,472 @@
-+/*
-+ * linux/drivers/video/cfbcon_decor.c -- Framebuffer decor render functions
-+ *
-+ * Copyright (C) 2004 Michal Januszewski <michalj+fbcondecor@gmail.com>
-+ *
-+ * Code based upon "Bootdecor" (C) 2001-2003
-+ * Volker Poplawski <volker@poplawski.de>,
-+ * Stefan Reinauer <stepan@suse.de>,
-+ * Steffen Winterfeldt <snwint@suse.de>,
-+ * Michael Schroeder <mls@suse.de>,
-+ * Ken Wimer <wimer@suse.de>.
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file COPYING in the main directory of this archive for
-+ * more details.
-+ */
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/fb.h>
-+#include <linux/selection.h>
-+#include <linux/slab.h>
-+#include <linux/vt_kern.h>
-+#include <asm/irq.h>
-+
-+#include "../fbdev/core/fbcon.h"
-+#include "fbcondecor.h"
-+
-+#define parse_pixel(shift, bpp, type) \
-+ do { \
-+ if (d & (0x80 >> (shift))) \
-+ dd2[(shift)] = fgx; \
-+ else \
-+ dd2[(shift)] = transparent ? *(type *)decor_src : bgx; \
-+ decor_src += (bpp); \
-+ } while (0) \
-+
-+extern int get_color(struct vc_data *vc, struct fb_info *info,
-+ u16 c, int is_fg);
-+
-+void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc)
-+{
-+ int i, j, k;
-+ int minlen = min(min(info->var.red.length, info->var.green.length),
-+ info->var.blue.length);
-+ u32 col;
-+
-+ for (j = i = 0; i < 16; i++) {
-+ k = color_table[i];
-+
-+ col = ((vc->vc_palette[j++] >> (8-minlen))
-+ << info->var.red.offset);
-+ col |= ((vc->vc_palette[j++] >> (8-minlen))
-+ << info->var.green.offset);
-+ col |= ((vc->vc_palette[j++] >> (8-minlen))
-+ << info->var.blue.offset);
-+ ((u32 *)info->pseudo_palette)[k] = col;
-+ }
-+}
-+
-+void fbcon_decor_renderc(struct fb_info *info, int ypos, int xpos, int height,
-+ int width, u8 *src, u32 fgx, u32 bgx, u8 transparent)
-+{
-+ unsigned int x, y;
-+ u32 dd;
-+ int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
-+ unsigned int d = ypos * info->fix.line_length + xpos * bytespp;
-+ unsigned int ds = (ypos * info->var.xres + xpos) * bytespp;
-+ u16 dd2[4];
-+
-+ u8 *decor_src = (u8 *)(info->bgdecor.data + ds);
-+ u8 *dst = (u8 *)(info->screen_base + d);
-+
-+ if ((ypos + height) > info->var.yres || (xpos + width) > info->var.xres)
-+ return;
-+
-+ for (y = 0; y < height; y++) {
-+ switch (info->var.bits_per_pixel) {
-+
-+ case 32:
-+ for (x = 0; x < width; x++) {
-+
-+ if ((x & 7) == 0)
-+ d = *src++;
-+ if (d & 0x80)
-+ dd = fgx;
-+ else
-+ dd = transparent ?
-+ *(u32 *)decor_src : bgx;
-+
-+ d <<= 1;
-+ decor_src += 4;
-+ fb_writel(dd, dst);
-+ dst += 4;
-+ }
-+ break;
-+ case 24:
-+ for (x = 0; x < width; x++) {
-+
-+ if ((x & 7) == 0)
-+ d = *src++;
-+ if (d & 0x80)
-+ dd = fgx;
-+ else
-+ dd = transparent ?
-+ (*(u32 *)decor_src & 0xffffff) : bgx;
-+
-+ d <<= 1;
-+ decor_src += 3;
-+#ifdef __LITTLE_ENDIAN
-+ fb_writew(dd & 0xffff, dst);
-+ dst += 2;
-+ fb_writeb((dd >> 16), dst);
-+#else
-+ fb_writew(dd >> 8, dst);
-+ dst += 2;
-+ fb_writeb(dd & 0xff, dst);
-+#endif
-+ dst++;
-+ }
-+ break;
-+ case 16:
-+ for (x = 0; x < width; x += 2) {
-+ if ((x & 7) == 0)
-+ d = *src++;
-+
-+ parse_pixel(0, 2, u16);
-+ parse_pixel(1, 2, u16);
-+#ifdef __LITTLE_ENDIAN
-+ dd = dd2[0] | (dd2[1] << 16);
-+#else
-+ dd = dd2[1] | (dd2[0] << 16);
-+#endif
-+ d <<= 2;
-+ fb_writel(dd, dst);
-+ dst += 4;
-+ }
-+ break;
-+
-+ case 8:
-+ for (x = 0; x < width; x += 4) {
-+ if ((x & 7) == 0)
-+ d = *src++;
-+
-+ parse_pixel(0, 1, u8);
-+ parse_pixel(1, 1, u8);
-+ parse_pixel(2, 1, u8);
-+ parse_pixel(3, 1, u8);
-+
-+#ifdef __LITTLE_ENDIAN
-+ dd = dd2[0] | (dd2[1] << 8) | (dd2[2] << 16) | (dd2[3] << 24);
-+#else
-+ dd = dd2[3] | (dd2[2] << 8) | (dd2[1] << 16) | (dd2[0] << 24);
-+#endif
-+ d <<= 4;
-+ fb_writel(dd, dst);
-+ dst += 4;
-+ }
-+ }
-+
-+ dst += info->fix.line_length - width * bytespp;
-+ decor_src += (info->var.xres - width) * bytespp;
-+ }
-+}
-+
-+#define cc2cx(a) \
-+ ((info->fix.visual == FB_VISUAL_TRUECOLOR || \
-+ info->fix.visual == FB_VISUAL_DIRECTCOLOR) ? \
-+ ((u32 *)info->pseudo_palette)[a] : a)
-+
-+void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info,
-+ const unsigned short *s, int count, int yy, int xx)
-+{
-+ unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
-+ struct fbcon_ops *ops = info->fbcon_par;
-+ int fg_color, bg_color, transparent;
-+ u8 *src;
-+ u32 bgx, fgx;
-+ u16 c = scr_readw(s);
-+
-+ fg_color = get_color(vc, info, c, 1);
-+ bg_color = get_color(vc, info, c, 0);
-+
-+ /* Don't paint the background image if console is blanked */
-+ transparent = ops->blank_state ? 0 :
-+ (vc->vc_decor.bg_color == bg_color);
-+
-+ xx = xx * vc->vc_font.width + vc->vc_decor.tx;
-+ yy = yy * vc->vc_font.height + vc->vc_decor.ty;
-+
-+ fgx = cc2cx(fg_color);
-+ bgx = cc2cx(bg_color);
-+
-+ while (count--) {
-+ c = scr_readw(s++);
-+ src = vc->vc_font.data + (c & charmask) * vc->vc_font.height *
-+ ((vc->vc_font.width + 7) >> 3);
-+
-+ fbcon_decor_renderc(info, yy, xx, vc->vc_font.height,
-+ vc->vc_font.width, src, fgx, bgx, transparent);
-+ xx += vc->vc_font.width;
-+ }
-+}
-+
-+void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor)
-+{
-+ int i;
-+ unsigned int dsize, s_pitch;
-+ struct fbcon_ops *ops = info->fbcon_par;
-+ struct vc_data *vc;
-+ u8 *src;
-+
-+ /* we really don't need any cursors while the console is blanked */
-+ if (info->state != FBINFO_STATE_RUNNING || ops->blank_state)
-+ return;
-+
-+ vc = vc_cons[ops->currcon].d;
-+
-+ src = kmalloc(64 + sizeof(struct fb_image), GFP_ATOMIC);
-+ if (!src)
-+ return;
-+
-+ s_pitch = (cursor->image.width + 7) >> 3;
-+ dsize = s_pitch * cursor->image.height;
-+ if (cursor->enable) {
-+ switch (cursor->rop) {
-+ case ROP_XOR:
-+ for (i = 0; i < dsize; i++)
-+ src[i] = cursor->image.data[i] ^ cursor->mask[i];
-+ break;
-+ case ROP_COPY:
-+ default:
-+ for (i = 0; i < dsize; i++)
-+ src[i] = cursor->image.data[i] & cursor->mask[i];
-+ break;
-+ }
-+ } else
-+ memcpy(src, cursor->image.data, dsize);
-+
-+ fbcon_decor_renderc(info,
-+ cursor->image.dy + vc->vc_decor.ty,
-+ cursor->image.dx + vc->vc_decor.tx,
-+ cursor->image.height,
-+ cursor->image.width,
-+ (u8 *)src,
-+ cc2cx(cursor->image.fg_color),
-+ cc2cx(cursor->image.bg_color),
-+ cursor->image.bg_color == vc->vc_decor.bg_color);
-+
-+ kfree(src);
-+}
-+
-+static void decorset(u8 *dst, int height, int width, int dstbytes,
-+ u32 bgx, int bpp)
-+{
-+ int i;
-+
-+ if (bpp == 8)
-+ bgx |= bgx << 8;
-+ if (bpp == 16 || bpp == 8)
-+ bgx |= bgx << 16;
-+
-+ while (height-- > 0) {
-+ u8 *p = dst;
-+
-+ switch (bpp) {
-+
-+ case 32:
-+ for (i = 0; i < width; i++) {
-+ fb_writel(bgx, p); p += 4;
-+ }
-+ break;
-+ case 24:
-+ for (i = 0; i < width; i++) {
-+#ifdef __LITTLE_ENDIAN
-+ fb_writew((bgx & 0xffff), (u16 *)p); p += 2;
-+ fb_writeb((bgx >> 16), p++);
-+#else
-+ fb_writew((bgx >> 8), (u16 *)p); p += 2;
-+ fb_writeb((bgx & 0xff), p++);
-+#endif
-+ }
-+ break;
-+ case 16:
-+ for (i = 0; i < width/4; i++) {
-+ fb_writel(bgx, p); p += 4;
-+ fb_writel(bgx, p); p += 4;
-+ }
-+ if (width & 2) {
-+ fb_writel(bgx, p); p += 4;
-+ }
-+ if (width & 1)
-+ fb_writew(bgx, (u16 *)p);
-+ break;
-+ case 8:
-+ for (i = 0; i < width/4; i++) {
-+ fb_writel(bgx, p); p += 4;
-+ }
-+
-+ if (width & 2) {
-+ fb_writew(bgx, p); p += 2;
-+ }
-+ if (width & 1)
-+ fb_writeb(bgx, (u8 *)p);
-+ break;
-+
-+ }
-+ dst += dstbytes;
-+ }
-+}
-+
-+void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes,
-+ int srclinebytes, int bpp)
-+{
-+ int i;
-+
-+ while (height-- > 0) {
-+ u32 *p = (u32 *)dst;
-+ u32 *q = (u32 *)src;
-+
-+ switch (bpp) {
-+
-+ case 32:
-+ for (i = 0; i < width; i++)
-+ fb_writel(*q++, p++);
-+ break;
-+ case 24:
-+ for (i = 0; i < (width * 3 / 4); i++)
-+ fb_writel(*q++, p++);
-+ if ((width * 3) % 4) {
-+ if (width & 2) {
-+ fb_writeb(*(u8 *)q, (u8 *)p);
-+ } else if (width & 1) {
-+ fb_writew(*(u16 *)q, (u16 *)p);
-+ fb_writeb(*(u8 *)((u16 *)q + 1),
-+ (u8 *)((u16 *)p + 2));
-+ }
-+ }
-+ break;
-+ case 16:
-+ for (i = 0; i < width/4; i++) {
-+ fb_writel(*q++, p++);
-+ fb_writel(*q++, p++);
-+ }
-+ if (width & 2)
-+ fb_writel(*q++, p++);
-+ if (width & 1)
-+ fb_writew(*(u16 *)q, (u16 *)p);
-+ break;
-+ case 8:
-+ for (i = 0; i < width/4; i++)
-+ fb_writel(*q++, p++);
-+
-+ if (width & 2) {
-+ fb_writew(*(u16 *)q, (u16 *)p);
-+ q = (u32 *) ((u16 *)q + 1);
-+ p = (u32 *) ((u16 *)p + 1);
-+ }
-+ if (width & 1)
-+ fb_writeb(*(u8 *)q, (u8 *)p);
-+ break;
-+ }
-+
-+ dst += linebytes;
-+ src += srclinebytes;
-+ }
-+}
-+
-+static void decorfill(struct fb_info *info, int sy, int sx, int height,
-+ int width)
-+{
-+ int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
-+ int d = sy * info->fix.line_length + sx * bytespp;
-+ int ds = (sy * info->var.xres + sx) * bytespp;
-+
-+ fbcon_decor_copy((u8 *)(info->screen_base + d), (u8 *)(info->bgdecor.data + ds),
-+ height, width, info->fix.line_length, info->var.xres * bytespp,
-+ info->var.bits_per_pixel);
-+}
-+
-+void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx,
-+ int height, int width)
-+{
-+ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
-+ struct fbcon_ops *ops = info->fbcon_par;
-+ u8 *dst;
-+ int transparent, bg_color = attr_bgcol_ec(bgshift, vc, info);
-+
-+ transparent = (vc->vc_decor.bg_color == bg_color);
-+ sy = sy * vc->vc_font.height + vc->vc_decor.ty;
-+ sx = sx * vc->vc_font.width + vc->vc_decor.tx;
-+ height *= vc->vc_font.height;
-+ width *= vc->vc_font.width;
-+
-+ /* Don't paint the background image if console is blanked */
-+ if (transparent && !ops->blank_state) {
-+ decorfill(info, sy, sx, height, width);
-+ } else {
-+ dst = (u8 *)(info->screen_base + sy * info->fix.line_length +
-+ sx * ((info->var.bits_per_pixel + 7) >> 3));
-+ decorset(dst, height, width, info->fix.line_length, cc2cx(bg_color),
-+ info->var.bits_per_pixel);
-+ }
-+}
-+
-+void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info,
-+ int bottom_only)
-+{
-+ unsigned int tw = vc->vc_cols*vc->vc_font.width;
-+ unsigned int th = vc->vc_rows*vc->vc_font.height;
-+
-+ if (!bottom_only) {
-+ /* top margin */
-+ decorfill(info, 0, 0, vc->vc_decor.ty, info->var.xres);
-+ /* left margin */
-+ decorfill(info, vc->vc_decor.ty, 0, th, vc->vc_decor.tx);
-+ /* right margin */
-+ decorfill(info, vc->vc_decor.ty, vc->vc_decor.tx + tw, th,
-+ info->var.xres - vc->vc_decor.tx - tw);
-+ }
-+ decorfill(info, vc->vc_decor.ty + th, 0,
-+ info->var.yres - vc->vc_decor.ty - th, info->var.xres);
-+}
-+
-+void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y,
-+ int sx, int dx, int width)
-+{
-+ u16 *d = (u16 *) (vc->vc_origin + vc->vc_size_row * y + dx * 2);
-+ u16 *s = d + (dx - sx);
-+ u16 *start = d;
-+ u16 *ls = d;
-+ u16 *le = d + width;
-+ u16 c;
-+ int x = dx;
-+ u16 attr = 1;
-+
-+ do {
-+ c = scr_readw(d);
-+ if (attr != (c & 0xff00)) {
-+ attr = c & 0xff00;
-+ if (d > start) {
-+ fbcon_decor_putcs(vc, info, start, d - start, y, x);
-+ x += d - start;
-+ start = d;
-+ }
-+ }
-+ if (s >= ls && s < le && c == scr_readw(s)) {
-+ if (d > start) {
-+ fbcon_decor_putcs(vc, info, start, d - start, y, x);
-+ x += d - start + 1;
-+ start = d + 1;
-+ } else {
-+ x++;
-+ start++;
-+ }
-+ }
-+ s++;
-+ d++;
-+ } while (d < le);
-+ if (d > start)
-+ fbcon_decor_putcs(vc, info, start, d - start, y, x);
-+}
-+
-+void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank)
-+{
-+ if (blank) {
-+ decorset((u8 *)info->screen_base, info->var.yres, info->var.xres,
-+ info->fix.line_length, 0, info->var.bits_per_pixel);
-+ } else {
-+ update_screen(vc);
-+ fbcon_decor_clear_margins(vc, info, 0);
-+ }
-+}
-diff --git a/drivers/video/console/fbcondecor.c b/drivers/video/console/fbcondecor.c
-new file mode 100644
-index 000000000000..78288a497a60
---- /dev/null
-+++ b/drivers/video/console/fbcondecor.c
-@@ -0,0 +1,549 @@
-+/*
-+ * linux/drivers/video/console/fbcondecor.c -- Framebuffer console decorations
-+ *
-+ * Copyright (C) 2004-2009 Michal Januszewski <michalj+fbcondecor@gmail.com>
-+ *
-+ * Code based upon "Bootsplash" (C) 2001-2003
-+ * Volker Poplawski <volker@poplawski.de>,
-+ * Stefan Reinauer <stepan@suse.de>,
-+ * Steffen Winterfeldt <snwint@suse.de>,
-+ * Michael Schroeder <mls@suse.de>,
-+ * Ken Wimer <wimer@suse.de>.
-+ *
-+ * Compat ioctl support by Thorsten Klein <TK@Thorsten-Klein.de>.
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file COPYING in the main directory of this archive for
-+ * more details.
-+ *
-+ */
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/string.h>
-+#include <linux/types.h>
-+#include <linux/fb.h>
-+#include <linux/vt_kern.h>
-+#include <linux/vmalloc.h>
-+#include <linux/unistd.h>
-+#include <linux/syscalls.h>
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/workqueue.h>
-+#include <linux/kmod.h>
-+#include <linux/miscdevice.h>
-+#include <linux/device.h>
-+#include <linux/fs.h>
-+#include <linux/compat.h>
-+#include <linux/console.h>
-+#include <linux/binfmts.h>
-+#include <linux/uaccess.h>
-+#include <asm/irq.h>
-+
-+#include "../fbdev/core/fbcon.h"
-+#include "fbcondecor.h"
-+
-+extern signed char con2fb_map[];
-+static int fbcon_decor_enable(struct vc_data *vc);
-+
-+static int initialized;
-+
-+char fbcon_decor_path[KMOD_PATH_LEN] = "/sbin/fbcondecor_helper";
-+EXPORT_SYMBOL(fbcon_decor_path);
-+
-+int fbcon_decor_call_helper(char *cmd, unsigned short vc)
-+{
-+ char *envp[] = {
-+ "HOME=/",
-+ "PATH=/sbin:/bin",
-+ NULL
-+ };
-+
-+ char tfb[5];
-+ char tcons[5];
-+ unsigned char fb = (int) con2fb_map[vc];
-+
-+ char *argv[] = {
-+ fbcon_decor_path,
-+ "2",
-+ cmd,
-+ tcons,
-+ tfb,
-+ vc_cons[vc].d->vc_decor.theme,
-+ NULL
-+ };
-+
-+ snprintf(tfb, 5, "%d", fb);
-+ snprintf(tcons, 5, "%d", vc);
-+
-+ return call_usermodehelper(fbcon_decor_path, argv, envp, UMH_WAIT_EXEC);
-+}
-+
-+/* Disables fbcondecor on a virtual console; called with console sem held. */
-+int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw)
-+{
-+ struct fb_info *info;
-+
-+ if (!vc->vc_decor.state)
-+ return -EINVAL;
-+
-+ info = registered_fb[(int) con2fb_map[vc->vc_num]];
-+
-+ if (info == NULL)
-+ return -EINVAL;
-+
-+ vc->vc_decor.state = 0;
-+ vc_resize(vc, info->var.xres / vc->vc_font.width,
-+ info->var.yres / vc->vc_font.height);
-+
-+ if (fg_console == vc->vc_num && redraw) {
-+ redraw_screen(vc, 0);
-+ update_region(vc, vc->vc_origin +
-+ vc->vc_size_row * vc->vc_top,
-+ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
-+ }
-+
-+ printk(KERN_INFO "fbcondecor: switched decor state to 'off' on console %d\n",
-+ vc->vc_num);
-+
-+ return 0;
-+}
-+
-+/* Enables fbcondecor on a virtual console; called with console sem held. */
-+static int fbcon_decor_enable(struct vc_data *vc)
-+{
-+ struct fb_info *info;
-+
-+ info = registered_fb[(int) con2fb_map[vc->vc_num]];
-+
-+ if (vc->vc_decor.twidth == 0 || vc->vc_decor.theight == 0 ||
-+ info == NULL || vc->vc_decor.state || (!info->bgdecor.data &&
-+ vc->vc_num == fg_console))
-+ return -EINVAL;
-+
-+ vc->vc_decor.state = 1;
-+ vc_resize(vc, vc->vc_decor.twidth / vc->vc_font.width,
-+ vc->vc_decor.theight / vc->vc_font.height);
-+
-+ if (fg_console == vc->vc_num) {
-+ redraw_screen(vc, 0);
-+ update_region(vc, vc->vc_origin +
-+ vc->vc_size_row * vc->vc_top,
-+ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
-+ fbcon_decor_clear_margins(vc, info, 0);
-+ }
-+
-+ printk(KERN_INFO "fbcondecor: switched decor state to 'on' on console %d\n",
-+ vc->vc_num);
-+
-+ return 0;
-+}
-+
-+static inline int fbcon_decor_ioctl_dosetstate(struct vc_data *vc, unsigned int state, unsigned char origin)
-+{
-+ int ret;
-+
-+ console_lock();
-+ if (!state)
-+ ret = fbcon_decor_disable(vc, 1);
-+ else
-+ ret = fbcon_decor_enable(vc);
-+ console_unlock();
-+
-+ return ret;
-+}
-+
-+static inline void fbcon_decor_ioctl_dogetstate(struct vc_data *vc, unsigned int *state)
-+{
-+ *state = vc->vc_decor.state;
-+}
-+
-+static int fbcon_decor_ioctl_dosetcfg(struct vc_data *vc, struct vc_decor *cfg, unsigned char origin)
-+{
-+ struct fb_info *info;
-+ int len;
-+ char *tmp;
-+
-+ info = registered_fb[(int) con2fb_map[vc->vc_num]];
-+
-+ if (info == NULL || !cfg->twidth || !cfg->theight ||
-+ cfg->tx + cfg->twidth > info->var.xres ||
-+ cfg->ty + cfg->theight > info->var.yres)
-+ return -EINVAL;
-+
-+ len = strnlen_user(cfg->theme, MAX_ARG_STRLEN);
-+ if (!len || len > FBCON_DECOR_THEME_LEN)
-+ return -EINVAL;
-+ tmp = kmalloc(len, GFP_KERNEL);
-+ if (!tmp)
-+ return -ENOMEM;
-+ if (copy_from_user(tmp, (void __user *)cfg->theme, len))
-+ return -EFAULT;
-+ cfg->theme = tmp;
-+ cfg->state = 0;
-+
-+ console_lock();
-+ if (vc->vc_decor.state)
-+ fbcon_decor_disable(vc, 1);
-+ kfree(vc->vc_decor.theme);
-+ vc->vc_decor = *cfg;
-+ console_unlock();
-+
-+ printk(KERN_INFO "fbcondecor: console %d using theme '%s'\n",
-+ vc->vc_num, vc->vc_decor.theme);
-+ return 0;
-+}
-+
-+static int fbcon_decor_ioctl_dogetcfg(struct vc_data *vc,
-+ struct vc_decor *decor)
-+{
-+ char __user *tmp;
-+
-+ tmp = decor->theme;
-+ *decor = vc->vc_decor;
-+ decor->theme = tmp;
-+
-+ if (vc->vc_decor.theme) {
-+ if (copy_to_user(tmp, vc->vc_decor.theme,
-+ strlen(vc->vc_decor.theme) + 1))
-+ return -EFAULT;
-+ } else
-+ if (put_user(0, tmp))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+
-+static int fbcon_decor_ioctl_dosetpic(struct vc_data *vc, struct fb_image *img,
-+ unsigned char origin)
-+{
-+ struct fb_info *info;
-+ int len;
-+ u8 *tmp;
-+
-+ if (vc->vc_num != fg_console)
-+ return -EINVAL;
-+
-+ info = registered_fb[(int) con2fb_map[vc->vc_num]];
-+
-+ if (info == NULL)
-+ return -EINVAL;
-+
-+ if (img->width != info->var.xres || img->height != info->var.yres) {
-+ printk(KERN_ERR "fbcondecor: picture dimensions mismatch\n");
-+ printk(KERN_ERR "%dx%d vs %dx%d\n", img->width, img->height,
-+ info->var.xres, info->var.yres);
-+ return -EINVAL;
-+ }
-+
-+ if (img->depth != info->var.bits_per_pixel) {
-+ printk(KERN_ERR "fbcondecor: picture depth mismatch\n");
-+ return -EINVAL;
-+ }
-+
-+ if (img->depth == 8) {
-+ if (!img->cmap.len || !img->cmap.red || !img->cmap.green ||
-+ !img->cmap.blue)
-+ return -EINVAL;
-+
-+ tmp = vmalloc(img->cmap.len * 3 * 2);
-+ if (!tmp)
-+ return -ENOMEM;
-+
-+ if (copy_from_user(tmp,
-+ (void __user *)img->cmap.red,
-+ (img->cmap.len << 1)) ||
-+ copy_from_user(tmp + (img->cmap.len << 1),
-+ (void __user *)img->cmap.green,
-+ (img->cmap.len << 1)) ||
-+ copy_from_user(tmp + (img->cmap.len << 2),
-+ (void __user *)img->cmap.blue,
-+ (img->cmap.len << 1))) {
-+ vfree(tmp);
-+ return -EFAULT;
-+ }
-+
-+ img->cmap.transp = NULL;
-+ img->cmap.red = (u16 *)tmp;
-+ img->cmap.green = img->cmap.red + img->cmap.len;
-+ img->cmap.blue = img->cmap.green + img->cmap.len;
-+ } else {
-+ img->cmap.red = NULL;
-+ }
-+
-+ len = ((img->depth + 7) >> 3) * img->width * img->height;
-+
-+ /*
-+ * Allocate an additional byte so that we never go outside of the
-+ * buffer boundaries in the rendering functions in a 24 bpp mode.
-+ */
-+ tmp = vmalloc(len + 1);
-+
-+ if (!tmp)
-+ goto out;
-+
-+ if (copy_from_user(tmp, (void __user *)img->data, len))
-+ goto out;
-+
-+ img->data = tmp;
-+
-+ console_lock();
-+
-+ if (info->bgdecor.data)
-+ vfree((u8 *)info->bgdecor.data);
-+ if (info->bgdecor.cmap.red)
-+ vfree(info->bgdecor.cmap.red);
-+
-+ info->bgdecor = *img;
-+
-+ if (fbcon_decor_active_vc(vc) && fg_console == vc->vc_num) {
-+ redraw_screen(vc, 0);
-+ update_region(vc, vc->vc_origin +
-+ vc->vc_size_row * vc->vc_top,
-+ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
-+ fbcon_decor_clear_margins(vc, info, 0);
-+ }
-+
-+ console_unlock();
-+
-+ return 0;
-+
-+out:
-+ if (img->cmap.red)
-+ vfree(img->cmap.red);
-+
-+ if (tmp)
-+ vfree(tmp);
-+ return -ENOMEM;
-+}
-+
-+static long fbcon_decor_ioctl(struct file *filp, u_int cmd, u_long arg)
-+{
-+ struct fbcon_decor_iowrapper __user *wrapper = (void __user *) arg;
-+ struct vc_data *vc = NULL;
-+ unsigned short vc_num = 0;
-+ unsigned char origin = 0;
-+ void __user *data = NULL;
-+
-+ if (!access_ok(VERIFY_READ, wrapper,
-+ sizeof(struct fbcon_decor_iowrapper)))
-+ return -EFAULT;
-+
-+ __get_user(vc_num, &wrapper->vc);
-+ __get_user(origin, &wrapper->origin);
-+ __get_user(data, &wrapper->data);
-+
-+ if (!vc_cons_allocated(vc_num))
-+ return -EINVAL;
-+
-+ vc = vc_cons[vc_num].d;
-+
-+ switch (cmd) {
-+ case FBIOCONDECOR_SETPIC:
-+ {
-+ struct fb_image img;
-+
-+ if (copy_from_user(&img, (struct fb_image __user *)data, sizeof(struct fb_image)))
-+ return -EFAULT;
-+
-+ return fbcon_decor_ioctl_dosetpic(vc, &img, origin);
-+ }
-+ case FBIOCONDECOR_SETCFG:
-+ {
-+ struct vc_decor cfg;
-+
-+ if (copy_from_user(&cfg, (struct vc_decor __user *)data, sizeof(struct vc_decor)))
-+ return -EFAULT;
-+
-+ return fbcon_decor_ioctl_dosetcfg(vc, &cfg, origin);
-+ }
-+ case FBIOCONDECOR_GETCFG:
-+ {
-+ int rval;
-+ struct vc_decor cfg;
-+
-+ if (copy_from_user(&cfg, (struct vc_decor __user *)data, sizeof(struct vc_decor)))
-+ return -EFAULT;
-+
-+ rval = fbcon_decor_ioctl_dogetcfg(vc, &cfg);
-+
-+ if (copy_to_user(data, &cfg, sizeof(struct vc_decor)))
-+ return -EFAULT;
-+ return rval;
-+ }
-+ case FBIOCONDECOR_SETSTATE:
-+ {
-+ unsigned int state = 0;
-+
-+ if (get_user(state, (unsigned int __user *)data))
-+ return -EFAULT;
-+ return fbcon_decor_ioctl_dosetstate(vc, state, origin);
-+ }
-+ case FBIOCONDECOR_GETSTATE:
-+ {
-+ unsigned int state = 0;
-+
-+ fbcon_decor_ioctl_dogetstate(vc, &state);
-+ return put_user(state, (unsigned int __user *)data);
-+ }
-+
-+ default:
-+ return -ENOIOCTLCMD;
-+ }
-+}
-+
-+#ifdef CONFIG_COMPAT
-+
-+static long fbcon_decor_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-+{
-+ struct fbcon_decor_iowrapper32 __user *wrapper = (void __user *)arg;
-+ struct vc_data *vc = NULL;
-+ unsigned short vc_num = 0;
-+ unsigned char origin = 0;
-+ compat_uptr_t data_compat = 0;
-+ void __user *data = NULL;
-+
-+ if (!access_ok(VERIFY_READ, wrapper,
-+ sizeof(struct fbcon_decor_iowrapper32)))
-+ return -EFAULT;
-+
-+ __get_user(vc_num, &wrapper->vc);
-+ __get_user(origin, &wrapper->origin);
-+ __get_user(data_compat, &wrapper->data);
-+ data = compat_ptr(data_compat);
-+
-+ if (!vc_cons_allocated(vc_num))
-+ return -EINVAL;
-+
-+ vc = vc_cons[vc_num].d;
-+
-+ switch (cmd) {
-+ case FBIOCONDECOR_SETPIC32:
-+ {
-+ struct fb_image32 img_compat;
-+ struct fb_image img;
-+
-+ if (copy_from_user(&img_compat, (struct fb_image32 __user *)data, sizeof(struct fb_image32)))
-+ return -EFAULT;
-+
-+ fb_image_from_compat(img, img_compat);
-+
-+ return fbcon_decor_ioctl_dosetpic(vc, &img, origin);
-+ }
-+
-+ case FBIOCONDECOR_SETCFG32:
-+ {
-+ struct vc_decor32 cfg_compat;
-+ struct vc_decor cfg;
-+
-+ if (copy_from_user(&cfg_compat, (struct vc_decor32 __user *)data, sizeof(struct vc_decor32)))
-+ return -EFAULT;
-+
-+ vc_decor_from_compat(cfg, cfg_compat);
-+
-+ return fbcon_decor_ioctl_dosetcfg(vc, &cfg, origin);
-+ }
-+
-+ case FBIOCONDECOR_GETCFG32:
-+ {
-+ int rval;
-+ struct vc_decor32 cfg_compat;
-+ struct vc_decor cfg;
-+
-+ if (copy_from_user(&cfg_compat, (struct vc_decor32 __user *)data, sizeof(struct vc_decor32)))
-+ return -EFAULT;
-+ cfg.theme = compat_ptr(cfg_compat.theme);
-+
-+ rval = fbcon_decor_ioctl_dogetcfg(vc, &cfg);
-+
-+ vc_decor_to_compat(cfg_compat, cfg);
-+
-+ if (copy_to_user((struct vc_decor32 __user *)data, &cfg_compat, sizeof(struct vc_decor32)))
-+ return -EFAULT;
-+ return rval;
-+ }
-+
-+ case FBIOCONDECOR_SETSTATE32:
-+ {
-+ compat_uint_t state_compat = 0;
-+ unsigned int state = 0;
-+
-+ if (get_user(state_compat, (compat_uint_t __user *)data))
-+ return -EFAULT;
-+
-+ state = (unsigned int)state_compat;
-+
-+ return fbcon_decor_ioctl_dosetstate(vc, state, origin);
-+ }
-+
-+ case FBIOCONDECOR_GETSTATE32:
-+ {
-+ compat_uint_t state_compat = 0;
-+ unsigned int state = 0;
-+
-+ fbcon_decor_ioctl_dogetstate(vc, &state);
-+ state_compat = (compat_uint_t)state;
-+
-+ return put_user(state_compat, (compat_uint_t __user *)data);
-+ }
-+
-+ default:
-+ return -ENOIOCTLCMD;
-+ }
-+}
-+#else
-+ #define fbcon_decor_compat_ioctl NULL
-+#endif
-+
-+static struct file_operations fbcon_decor_ops = {
-+ .owner = THIS_MODULE,
-+ .unlocked_ioctl = fbcon_decor_ioctl,
-+ .compat_ioctl = fbcon_decor_compat_ioctl
-+};
-+
-+static struct miscdevice fbcon_decor_dev = {
-+ .minor = MISC_DYNAMIC_MINOR,
-+ .name = "fbcondecor",
-+ .fops = &fbcon_decor_ops
-+};
-+
-+void fbcon_decor_reset(void)
-+{
-+ int i;
-+
-+ for (i = 0; i < num_registered_fb; i++) {
-+ registered_fb[i]->bgdecor.data = NULL;
-+ registered_fb[i]->bgdecor.cmap.red = NULL;
-+ }
-+
-+ for (i = 0; i < MAX_NR_CONSOLES && vc_cons[i].d; i++) {
-+ vc_cons[i].d->vc_decor.state = vc_cons[i].d->vc_decor.twidth =
-+ vc_cons[i].d->vc_decor.theight = 0;
-+ vc_cons[i].d->vc_decor.theme = NULL;
-+ }
-+}
-+
-+int fbcon_decor_init(void)
-+{
-+ int i;
-+
-+ fbcon_decor_reset();
-+
-+ if (initialized)
-+ return 0;
-+
-+ i = misc_register(&fbcon_decor_dev);
-+ if (i) {
-+ printk(KERN_ERR "fbcondecor: failed to register device\n");
-+ return i;
-+ }
-+
-+ fbcon_decor_call_helper("init", 0);
-+ initialized = 1;
-+ return 0;
-+}
-+
-+int fbcon_decor_exit(void)
-+{
-+ fbcon_decor_reset();
-+ return 0;
-+}
-diff --git a/drivers/video/console/fbcondecor.h b/drivers/video/console/fbcondecor.h
-new file mode 100644
-index 000000000000..c49386c16695
---- /dev/null
-+++ b/drivers/video/console/fbcondecor.h
-@@ -0,0 +1,77 @@
-+/*
-+ * linux/drivers/video/console/fbcondecor.h -- Framebuffer Console Decoration headers
-+ *
-+ * Copyright (C) 2004 Michal Januszewski <michalj+fbcondecor@gmail.com>
-+ *
-+ */
-+
-+#ifndef __FBCON_DECOR_H
-+#define __FBCON_DECOR_H
-+
-+#ifndef _LINUX_FB_H
-+#include <linux/fb.h>
-+#endif
-+
-+/* This is needed for vc_cons in fbcmap.c */
-+#include <linux/vt_kern.h>
-+
-+struct fb_cursor;
-+struct fb_info;
-+struct vc_data;
-+
-+#ifdef CONFIG_FB_CON_DECOR
-+/* fbcondecor.c */
-+int fbcon_decor_init(void);
-+int fbcon_decor_exit(void);
-+int fbcon_decor_call_helper(char *cmd, unsigned short cons);
-+int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw);
-+
-+/* cfbcondecor.c */
-+void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx);
-+void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor);
-+void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width);
-+void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only);
-+void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank);
-+void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width);
-+void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes, int srclinesbytes, int bpp);
-+void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc);
-+
-+/* vt.c */
-+void acquire_console_sem(void);
-+void release_console_sem(void);
-+void do_unblank_screen(int entering_gfx);
-+
-+/* struct vc_data *y */
-+#define fbcon_decor_active_vc(y) (y->vc_decor.state && y->vc_decor.theme)
-+
-+/* struct fb_info *x, struct vc_data *y */
-+#define fbcon_decor_active_nores(x, y) (x->bgdecor.data && fbcon_decor_active_vc(y))
-+
-+/* struct fb_info *x, struct vc_data *y */
-+#define fbcon_decor_active(x, y) (fbcon_decor_active_nores(x, y) && \
-+ x->bgdecor.width == x->var.xres && \
-+ x->bgdecor.height == x->var.yres && \
-+ x->bgdecor.depth == x->var.bits_per_pixel)
-+
-+#else /* CONFIG_FB_CON_DECOR */
-+
-+static inline void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx) {}
-+static inline void fbcon_decor_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos) {}
-+static inline void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor) {}
-+static inline void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width) {}
-+static inline void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only) {}
-+static inline void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank) {}
-+static inline void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width) {}
-+static inline void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc) {}
-+static inline int fbcon_decor_call_helper(char *cmd, unsigned short cons) { return 0; }
-+static inline int fbcon_decor_init(void) { return 0; }
-+static inline int fbcon_decor_exit(void) { return 0; }
-+static inline int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw) { return 0; }
-+
-+#define fbcon_decor_active_vc(y) (0)
-+#define fbcon_decor_active_nores(x, y) (0)
-+#define fbcon_decor_active(x, y) (0)
-+
-+#endif /* CONFIG_FB_CON_DECOR */
-+
-+#endif /* __FBCON_DECOR_H */
-diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
-index 11e699f1062b..f6fb26aca16d 100644
---- a/drivers/video/fbdev/Kconfig
-+++ b/drivers/video/fbdev/Kconfig
-@@ -1216,7 +1216,6 @@ config FB_MATROX
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
-- select FB_TILEBLITTING
- select FB_MACMODES if PPC_PMAC
- ---help---
- Say Y here if you have a Matrox Millennium, Matrox Millennium II,
-diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c
-index 790900d646c0..3f940c93752c 100644
---- a/drivers/video/fbdev/core/bitblit.c
-+++ b/drivers/video/fbdev/core/bitblit.c
-@@ -18,6 +18,7 @@
- #include <linux/console.h>
- #include <asm/types.h>
- #include "fbcon.h"
-+#include "../../console/fbcondecor.h"
-
- /*
- * Accelerated handlers.
-@@ -55,6 +56,13 @@ static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy,
- area.height = height * vc->vc_font.height;
- area.width = width * vc->vc_font.width;
-
-+ if (fbcon_decor_active(info, vc)) {
-+ area.sx += vc->vc_decor.tx;
-+ area.sy += vc->vc_decor.ty;
-+ area.dx += vc->vc_decor.tx;
-+ area.dy += vc->vc_decor.ty;
-+ }
-+
- info->fbops->fb_copyarea(info, &area);
- }
-
-@@ -379,11 +387,15 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
- cursor.image.depth = 1;
- cursor.rop = ROP_XOR;
-
-- if (info->fbops->fb_cursor)
-- err = info->fbops->fb_cursor(info, &cursor);
-+ if (fbcon_decor_active(info, vc)) {
-+ fbcon_decor_cursor(info, &cursor);
-+ } else {
-+ if (info->fbops->fb_cursor)
-+ err = info->fbops->fb_cursor(info, &cursor);
-
-- if (err)
-- soft_cursor(info, &cursor);
-+ if (err)
-+ soft_cursor(info, &cursor);
-+ }
-
- ops->cursor_reset = 0;
- }
-diff --git a/drivers/video/fbdev/core/fbcmap.c b/drivers/video/fbdev/core/fbcmap.c
-index 68a113594808..21f977cb59d2 100644
---- a/drivers/video/fbdev/core/fbcmap.c
-+++ b/drivers/video/fbdev/core/fbcmap.c
-@@ -17,6 +17,8 @@
- #include <linux/slab.h>
- #include <linux/uaccess.h>
-
-+#include "../../console/fbcondecor.h"
-+
- static u16 red2[] __read_mostly = {
- 0x0000, 0xaaaa
- };
-@@ -256,9 +258,12 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info)
- break;
- }
- }
-- if (rc == 0)
-+ if (rc == 0) {
- fb_copy_cmap(cmap, &info->cmap);
--
-+ if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
-+ info->fix.visual == FB_VISUAL_DIRECTCOLOR)
-+ fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
-+ }
- return rc;
- }
-
-diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
-index 5baf7bc054e1..e16f36d10bb8 100644
---- a/drivers/video/fbdev/core/fbcon.c
-+++ b/drivers/video/fbdev/core/fbcon.c
-@@ -80,6 +80,7 @@
- #include <asm/irq.h>
-
- #include "fbcon.h"
-+#include "../../console/fbcondecor.h"
-
- #ifdef FBCONDEBUG
- # define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
-@@ -95,7 +96,7 @@ enum {
-
- static struct display fb_display[MAX_NR_CONSOLES];
-
--static signed char con2fb_map[MAX_NR_CONSOLES];
-+signed char con2fb_map[MAX_NR_CONSOLES];
- static signed char con2fb_map_boot[MAX_NR_CONSOLES];
-
- static int logo_lines;
-@@ -282,7 +283,7 @@ static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
- !vt_force_oops_output(vc);
- }
-
--static int get_color(struct vc_data *vc, struct fb_info *info,
-+int get_color(struct vc_data *vc, struct fb_info *info,
- u16 c, int is_fg)
- {
- int depth = fb_get_color_depth(&info->var, &info->fix);
-@@ -550,6 +551,9 @@ static int do_fbcon_takeover(int show_logo)
- info_idx = -1;
- } else {
- fbcon_has_console_bind = 1;
-+#ifdef CONFIG_FB_CON_DECOR
-+ fbcon_decor_init();
-+#endif
- }
-
- return err;
-@@ -1017,6 +1021,12 @@ static const char *fbcon_startup(void)
- rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
- cols /= vc->vc_font.width;
- rows /= vc->vc_font.height;
-+
-+ if (fbcon_decor_active(info, vc)) {
-+ cols = vc->vc_decor.twidth / vc->vc_font.width;
-+ rows = vc->vc_decor.theight / vc->vc_font.height;
-+ }
-+
- vc_resize(vc, cols, rows);
-
- DPRINTK("mode: %s\n", info->fix.id);
-@@ -1046,7 +1056,7 @@ static void fbcon_init(struct vc_data *vc, int init)
- cap = info->flags;
-
- if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
-- (info->fix.type == FB_TYPE_TEXT))
-+ (info->fix.type == FB_TYPE_TEXT) || fbcon_decor_active(info, vc))
- logo = 0;
-
- if (var_to_display(p, &info->var, info))
-@@ -1282,6 +1292,11 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
- fbcon_clear_margins(vc, 0);
- }
-
-+ if (fbcon_decor_active(info, vc)) {
-+ fbcon_decor_clear(vc, info, sy, sx, height, width);
-+ return;
-+ }
-+
- /* Split blits that cross physical y_wrap boundary */
-
- y_break = p->vrows - p->yscroll;
-@@ -1301,10 +1316,15 @@ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
- struct display *p = &fb_display[vc->vc_num];
- struct fbcon_ops *ops = info->fbcon_par;
-
-- if (!fbcon_is_inactive(vc, info))
-- ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
-- get_color(vc, info, scr_readw(s), 1),
-- get_color(vc, info, scr_readw(s), 0));
-+ if (!fbcon_is_inactive(vc, info)) {
-+
-+ if (fbcon_decor_active(info, vc))
-+ fbcon_decor_putcs(vc, info, s, count, ypos, xpos);
-+ else
-+ ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
-+ get_color(vc, info, scr_readw(s), 1),
-+ get_color(vc, info, scr_readw(s), 0));
-+ }
- }
-
- static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
-@@ -1320,8 +1340,12 @@ static void fbcon_clear_margins(struct vc_data *vc, int bottom_only)
- struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
- struct fbcon_ops *ops = info->fbcon_par;
-
-- if (!fbcon_is_inactive(vc, info))
-- ops->clear_margins(vc, info, margin_color, bottom_only);
-+ if (!fbcon_is_inactive(vc, info)) {
-+ if (fbcon_decor_active(info, vc))
-+ fbcon_decor_clear_margins(vc, info, bottom_only);
-+ else
-+ ops->clear_margins(vc, info, margin_color, bottom_only);
-+ }
- }
-
- static void fbcon_cursor(struct vc_data *vc, int mode)
-@@ -1842,7 +1866,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
- count = vc->vc_rows;
- if (softback_top)
- fbcon_softback_note(vc, t, count);
-- if (logo_shown >= 0)
-+ if (logo_shown >= 0 || fbcon_decor_active(info, vc))
- goto redraw_up;
- switch (p->scrollmode) {
- case SCROLL_MOVE:
-@@ -1935,6 +1959,8 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
- count = vc->vc_rows;
- if (logo_shown >= 0)
- goto redraw_down;
-+ if (fbcon_decor_active(info, vc))
-+ goto redraw_down;
- switch (p->scrollmode) {
- case SCROLL_MOVE:
- fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
-@@ -2083,6 +2109,13 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s
- }
- return;
- }
-+
-+ if (fbcon_decor_active(info, vc) && sy == dy && height == 1) {
-+ /* must use slower redraw bmove to keep background pic intact */
-+ fbcon_decor_bmove_redraw(vc, info, sy, sx, dx, width);
-+ return;
-+ }
-+
- ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
- height, width);
- }
-@@ -2153,8 +2186,8 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
- var.yres = virt_h * virt_fh;
- x_diff = info->var.xres - var.xres;
- y_diff = info->var.yres - var.yres;
-- if (x_diff < 0 || x_diff > virt_fw ||
-- y_diff < 0 || y_diff > virt_fh) {
-+ if ((x_diff < 0 || x_diff > virt_fw ||
-+ y_diff < 0 || y_diff > virt_fh) && !vc->vc_decor.state) {
- const struct fb_videomode *mode;
-
- DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
-@@ -2190,6 +2223,22 @@ static int fbcon_switch(struct vc_data *vc)
-
- info = registered_fb[con2fb_map[vc->vc_num]];
- ops = info->fbcon_par;
-+ prev_console = ops->currcon;
-+ if (prev_console != -1)
-+ old_info = registered_fb[con2fb_map[prev_console]];
-+
-+#ifdef CONFIG_FB_CON_DECOR
-+ if (!fbcon_decor_active_vc(vc) && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
-+ struct vc_data *vc_curr = vc_cons[prev_console].d;
-+
-+ if (vc_curr && fbcon_decor_active_vc(vc_curr)) {
-+ // Clear the screen to avoid displaying funky colors
-+ // during palette updates.
-+ memset((u8 *)info->screen_base + info->fix.line_length * info->var.yoffset,
-+ 0, info->var.yres * info->fix.line_length);
-+ }
-+ }
-+#endif
-
- if (softback_top) {
- if (softback_lines)
-@@ -2208,9 +2257,6 @@ static int fbcon_switch(struct vc_data *vc)
- logo_shown = FBCON_LOGO_CANSHOW;
- }
-
-- prev_console = ops->currcon;
-- if (prev_console != -1)
-- old_info = registered_fb[con2fb_map[prev_console]];
- /*
- * FIXME: If we have multiple fbdev's loaded, we need to
- * update all info->currcon. Perhaps, we can place this
-@@ -2254,6 +2300,18 @@ static int fbcon_switch(struct vc_data *vc)
- fbcon_del_cursor_timer(old_info);
- }
-
-+ if (fbcon_decor_active_vc(vc)) {
-+ struct vc_data *vc_curr = vc_cons[prev_console].d;
-+
-+ if (!vc_curr->vc_decor.theme ||
-+ strcmp(vc->vc_decor.theme, vc_curr->vc_decor.theme) ||
-+ (fbcon_decor_active_nores(info, vc_curr) &&
-+ !fbcon_decor_active(info, vc_curr))) {
-+ fbcon_decor_disable(vc, 0);
-+ fbcon_decor_call_helper("modechange", vc->vc_num);
-+ }
-+ }
-+
- if (fbcon_is_inactive(vc, info) ||
- ops->blank_state != FB_BLANK_UNBLANK)
- fbcon_del_cursor_timer(info);
-@@ -2362,15 +2420,20 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
- }
- }
-
-- if (!fbcon_is_inactive(vc, info)) {
-+ if (!fbcon_is_inactive(vc, info)) {
- if (ops->blank_state != blank) {
- ops->blank_state = blank;
- fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
- ops->cursor_flash = (!blank);
-
-- if (!(info->flags & FBINFO_MISC_USEREVENT))
-- if (fb_blank(info, blank))
-- fbcon_generic_blank(vc, info, blank);
-+ if (!(info->flags & FBINFO_MISC_USEREVENT)) {
-+ if (fb_blank(info, blank)) {
-+ if (fbcon_decor_active(info, vc))
-+ fbcon_decor_blank(vc, info, blank);
-+ else
-+ fbcon_generic_blank(vc, info, blank);
-+ }
-+ }
- }
-
- if (!blank)
-@@ -2553,13 +2616,22 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
- set_vc_hi_font(vc, true);
-
- if (resize) {
-+ /* reset wrap/pan */
- int cols, rows;
-
- cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
- rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
-+
-+ if (fbcon_decor_active(info, vc)) {
-+ info->var.xoffset = info->var.yoffset = p->yscroll = 0;
-+ cols = vc->vc_decor.twidth;
-+ rows = vc->vc_decor.theight;
-+ }
- cols /= w;
- rows /= h;
-+
- vc_resize(vc, cols, rows);
-+
- if (con_is_visible(vc) && softback_buf)
- fbcon_update_softback(vc);
- } else if (con_is_visible(vc)
-@@ -2688,7 +2760,11 @@ static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table)
- int i, j, k, depth;
- u8 val;
-
-- if (fbcon_is_inactive(vc, info))
-+ if (fbcon_is_inactive(vc, info)
-+#ifdef CONFIG_FB_CON_DECOR
-+ || vc->vc_num != fg_console
-+#endif
-+ )
- return;
-
- if (!con_is_visible(vc))
-@@ -2714,7 +2790,47 @@ static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table)
- } else
- fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
-
-- fb_set_cmap(&palette_cmap, info);
-+ if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
-+ info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
-+
-+ u16 *red, *green, *blue;
-+ int minlen = min(min(info->var.red.length, info->var.green.length),
-+ info->var.blue.length);
-+
-+ struct fb_cmap cmap = {
-+ .start = 0,
-+ .len = (1 << minlen),
-+ .red = NULL,
-+ .green = NULL,
-+ .blue = NULL,
-+ .transp = NULL
-+ };
-+
-+ red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL);
-+
-+ if (!red)
-+ goto out;
-+
-+ green = red + 256;
-+ blue = green + 256;
-+ cmap.red = red;
-+ cmap.green = green;
-+ cmap.blue = blue;
-+
-+ for (i = 0; i < cmap.len; i++)
-+ red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1);
-+
-+ fb_set_cmap(&cmap, info);
-+ fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
-+ kfree(red);
-+
-+ return;
-+
-+ } else if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
-+ info->var.bits_per_pixel == 8 && info->bgdecor.cmap.red != NULL)
-+ fb_set_cmap(&info->bgdecor.cmap, info);
-+
-+out: fb_set_cmap(&palette_cmap, info);
- }
-
- static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
-@@ -2939,7 +3055,14 @@ static void fbcon_modechanged(struct fb_info *info)
- rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
- cols /= vc->vc_font.width;
- rows /= vc->vc_font.height;
-- vc_resize(vc, cols, rows);
-+
-+ if (!fbcon_decor_active_nores(info, vc)) {
-+ vc_resize(vc, cols, rows);
-+ } else {
-+ fbcon_decor_disable(vc, 0);
-+ fbcon_decor_call_helper("modechange", vc->vc_num);
-+ }
-+
- updatescrollmode(p, info, vc);
- scrollback_max = 0;
- scrollback_current = 0;
-@@ -2984,7 +3107,8 @@ static void fbcon_set_all_vcs(struct fb_info *info)
- rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
- cols /= vc->vc_font.width;
- rows /= vc->vc_font.height;
-- vc_resize(vc, cols, rows);
-+ if (!fbcon_decor_active_nores(info, vc))
-+ vc_resize(vc, cols, rows);
- }
-
- if (fg != -1)
-@@ -3625,6 +3749,7 @@ static void fbcon_exit(void)
- }
- }
-
-+ fbcon_decor_exit();
- fbcon_has_exited = 1;
- }
-
-diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
-index f741ba8df01b..b0141433d249 100644
---- a/drivers/video/fbdev/core/fbmem.c
-+++ b/drivers/video/fbdev/core/fbmem.c
-@@ -1253,15 +1253,6 @@ struct fb_fix_screeninfo32 {
- u16 reserved[3];
- };
-
--struct fb_cmap32 {
-- u32 start;
-- u32 len;
-- compat_caddr_t red;
-- compat_caddr_t green;
-- compat_caddr_t blue;
-- compat_caddr_t transp;
--};
--
- static int fb_getput_cmap(struct fb_info *info, unsigned int cmd,
- unsigned long arg)
- {
-diff --git a/include/linux/console_decor.h b/include/linux/console_decor.h
-new file mode 100644
-index 000000000000..15143556c2aa
---- /dev/null
-+++ b/include/linux/console_decor.h
-@@ -0,0 +1,46 @@
-+#ifndef _LINUX_CONSOLE_DECOR_H_
-+#define _LINUX_CONSOLE_DECOR_H_ 1
-+
-+/* A structure used by the framebuffer console decorations (drivers/video/console/fbcondecor.c) */
-+struct vc_decor {
-+ __u8 bg_color; /* The color that is to be treated as transparent */
-+ __u8 state; /* Current decor state: 0 = off, 1 = on */
-+ __u16 tx, ty; /* Top left corner coordinates of the text field */
-+ __u16 twidth, theight; /* Width and height of the text field */
-+ char *theme;
-+};
-+
-+#ifdef __KERNEL__
-+#ifdef CONFIG_COMPAT
-+#include <linux/compat.h>
-+
-+struct vc_decor32 {
-+ __u8 bg_color; /* The color that is to be treated as transparent */
-+ __u8 state; /* Current decor state: 0 = off, 1 = on */
-+ __u16 tx, ty; /* Top left corner coordinates of the text field */
-+ __u16 twidth, theight; /* Width and height of the text field */
-+ compat_uptr_t theme;
-+};
-+
-+#define vc_decor_from_compat(to, from) \
-+ (to).bg_color = (from).bg_color; \
-+ (to).state = (from).state; \
-+ (to).tx = (from).tx; \
-+ (to).ty = (from).ty; \
-+ (to).twidth = (from).twidth; \
-+ (to).theight = (from).theight; \
-+ (to).theme = compat_ptr((from).theme)
-+
-+#define vc_decor_to_compat(to, from) \
-+ (to).bg_color = (from).bg_color; \
-+ (to).state = (from).state; \
-+ (to).tx = (from).tx; \
-+ (to).ty = (from).ty; \
-+ (to).twidth = (from).twidth; \
-+ (to).theight = (from).theight; \
-+ (to).theme = ptr_to_compat((from).theme)
-+
-+#endif /* CONFIG_COMPAT */
-+#endif /* __KERNEL__ */
-+
-+#endif
-diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
-index c0ec478ea5bf..8bfed6b21fc9 100644
---- a/include/linux/console_struct.h
-+++ b/include/linux/console_struct.h
-@@ -21,6 +21,7 @@ struct vt_struct;
- struct uni_pagedir;
-
- #define NPAR 16
-+#include <linux/console_decor.h>
-
- /*
- * Example: vc_data of a console that was scrolled 3 lines down.
-@@ -141,6 +142,8 @@ struct vc_data {
- struct uni_pagedir *vc_uni_pagedir;
- struct uni_pagedir **vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */
- bool vc_panic_force_write; /* when oops/panic this VC can accept forced output/blanking */
-+
-+ struct vc_decor vc_decor;
- /* additional information is in vt_kern.h */
- };
-
-diff --git a/include/linux/fb.h b/include/linux/fb.h
-index f577d3c89618..3156bb6e305a 100644
---- a/include/linux/fb.h
-+++ b/include/linux/fb.h
-@@ -239,6 +239,34 @@ struct fb_deferred_io {
- };
- #endif
-
-+#ifdef __KERNEL__
-+#ifdef CONFIG_COMPAT
-+struct fb_image32 {
-+ __u32 dx; /* Where to place image */
-+ __u32 dy;
-+ __u32 width; /* Size of image */
-+ __u32 height;
-+ __u32 fg_color; /* Only used when a mono bitmap */
-+ __u32 bg_color;
-+ __u8 depth; /* Depth of the image */
-+ const compat_uptr_t data; /* Pointer to image data */
-+ struct fb_cmap32 cmap; /* color map info */
-+};
-+
-+#define fb_image_from_compat(to, from) \
-+ (to).dx = (from).dx; \
-+ (to).dy = (from).dy; \
-+ (to).width = (from).width; \
-+ (to).height = (from).height; \
-+ (to).fg_color = (from).fg_color; \
-+ (to).bg_color = (from).bg_color; \
-+ (to).depth = (from).depth; \
-+ (to).data = compat_ptr((from).data); \
-+ fb_cmap_from_compat((to).cmap, (from).cmap)
-+
-+#endif /* CONFIG_COMPAT */
-+#endif /* __KERNEL__ */
-+
- /*
- * Frame buffer operations
- *
-@@ -514,6 +542,9 @@ struct fb_info {
- #define FBINFO_STATE_SUSPENDED 1
- u32 state; /* Hardware state i.e suspend */
- void *fbcon_par; /* fbcon use-only private area */
-+
-+ struct fb_image bgdecor;
-+
- /* From here on everything is device dependent */
- void *par;
- /* we need the PCI or similar aperture base/size not
-diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h
-index 6cd9b198b7c6..a228440649fa 100644
---- a/include/uapi/linux/fb.h
-+++ b/include/uapi/linux/fb.h
-@@ -9,6 +9,23 @@
-
- #define FB_MAX 32 /* sufficient for now */
-
-+struct fbcon_decor_iowrapper {
-+ unsigned short vc; /* Virtual console */
-+ unsigned char origin; /* Point of origin of the request */
-+ void *data;
-+};
-+
-+#ifdef __KERNEL__
-+#ifdef CONFIG_COMPAT
-+#include <linux/compat.h>
-+struct fbcon_decor_iowrapper32 {
-+ unsigned short vc; /* Virtual console */
-+ unsigned char origin; /* Point of origin of the request */
-+ compat_uptr_t data;
-+};
-+#endif /* CONFIG_COMPAT */
-+#endif /* __KERNEL__ */
-+
- /* ioctls
- 0x46 is 'F' */
- #define FBIOGET_VSCREENINFO 0x4600
-@@ -36,6 +53,25 @@
- #define FBIOGET_DISPINFO 0x4618
- #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
-
-+#define FBIOCONDECOR_SETCFG _IOWR('F', 0x19, struct fbcon_decor_iowrapper)
-+#define FBIOCONDECOR_GETCFG _IOR('F', 0x1A, struct fbcon_decor_iowrapper)
-+#define FBIOCONDECOR_SETSTATE _IOWR('F', 0x1B, struct fbcon_decor_iowrapper)
-+#define FBIOCONDECOR_GETSTATE _IOR('F', 0x1C, struct fbcon_decor_iowrapper)
-+#define FBIOCONDECOR_SETPIC _IOWR('F', 0x1D, struct fbcon_decor_iowrapper)
-+#ifdef __KERNEL__
-+#ifdef CONFIG_COMPAT
-+#define FBIOCONDECOR_SETCFG32 _IOWR('F', 0x19, struct fbcon_decor_iowrapper32)
-+#define FBIOCONDECOR_GETCFG32 _IOR('F', 0x1A, struct fbcon_decor_iowrapper32)
-+#define FBIOCONDECOR_SETSTATE32 _IOWR('F', 0x1B, struct fbcon_decor_iowrapper32)
-+#define FBIOCONDECOR_GETSTATE32 _IOR('F', 0x1C, struct fbcon_decor_iowrapper32)
-+#define FBIOCONDECOR_SETPIC32 _IOWR('F', 0x1D, struct fbcon_decor_iowrapper32)
-+#endif /* CONFIG_COMPAT */
-+#endif /* __KERNEL__ */
-+
-+#define FBCON_DECOR_THEME_LEN 128 /* Maximum length of a theme name */
-+#define FBCON_DECOR_IO_ORIG_KERNEL 0 /* Kernel ioctl origin */
-+#define FBCON_DECOR_IO_ORIG_USER 1 /* User ioctl origin */
-+
- #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
- #define FB_TYPE_PLANES 1 /* Non interleaved planes */
- #define FB_TYPE_INTERLEAVED_PLANES 2 /* Interleaved planes */
-@@ -278,6 +314,29 @@ struct fb_var_screeninfo {
- __u32 reserved[4]; /* Reserved for future compatibility */
- };
-
-+#ifdef __KERNEL__
-+#ifdef CONFIG_COMPAT
-+struct fb_cmap32 {
-+ __u32 start;
-+ __u32 len; /* Number of entries */
-+ compat_uptr_t red; /* Red values */
-+ compat_uptr_t green;
-+ compat_uptr_t blue;
-+ compat_uptr_t transp; /* transparency, can be NULL */
-+};
-+
-+#define fb_cmap_from_compat(to, from) \
-+ (to).start = (from).start; \
-+ (to).len = (from).len; \
-+ (to).red = compat_ptr((from).red); \
-+ (to).green = compat_ptr((from).green); \
-+ (to).blue = compat_ptr((from).blue); \
-+ (to).transp = compat_ptr((from).transp)
-+
-+#endif /* CONFIG_COMPAT */
-+#endif /* __KERNEL__ */
-+
-+
- struct fb_cmap {
- __u32 start; /* First entry */
- __u32 len; /* Number of entries */
-diff --git a/kernel/sysctl.c b/kernel/sysctl.c
-index f98f28c12020..c2f4f6b34206 100644
---- a/kernel/sysctl.c
-+++ b/kernel/sysctl.c
-@@ -150,6 +150,10 @@ static const int cap_last_cap = CAP_LAST_CAP;
- static unsigned long hung_task_timeout_max = (LONG_MAX/HZ);
- #endif
-
-+#ifdef CONFIG_FB_CON_DECOR
-+extern char fbcon_decor_path[];
-+#endif
-+
- #ifdef CONFIG_INOTIFY_USER
- #include <linux/inotify.h>
- #endif
-@@ -285,6 +289,15 @@ static struct ctl_table sysctl_base_table[] = {
- .mode = 0555,
- .child = dev_table,
- },
-+#ifdef CONFIG_FB_CON_DECOR
-+ {
-+ .procname = "fbcondecor",
-+ .data = &fbcon_decor_path,
-+ .maxlen = KMOD_PATH_LEN,
-+ .mode = 0644,
-+ .proc_handler = &proc_dostring,
-+ },
-+#endif
- { }
- };
-
diff --git a/sys-kernel/boest-v4.16.18/0014-4.16-4400_alpha-sysctl-uac.patch.patch b/sys-kernel/boest-v4.16.18/0014-4.16-4400_alpha-sysctl-uac.patch.patch
deleted file mode 100644
index 37396971..00000000
--- a/sys-kernel/boest-v4.16.18/0014-4.16-4400_alpha-sysctl-uac.patch.patch
+++ /dev/null
@@ -1,153 +0,0 @@
-From 2fc901dfcb3ebad167fb3b0179f0830150581fdc Mon Sep 17 00:00:00 2001
-From: Mike Pagano <mpagano@gentoo.org>
-Date: Mon, 12 Feb 2018 15:44:07 -0500
-Subject: [PATCH 14/16] 4.16:4400_alpha-sysctl-uac.patch
-
----
- arch/alpha/Kconfig | 27 +++++++++++++++++++++++++
- arch/alpha/kernel/traps.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++
- kernel/sysctl.c | 12 +++++++++++
- 3 files changed, 90 insertions(+)
-
-diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
-index e96adcbcab41..ddf48b691337 100644
---- a/arch/alpha/Kconfig
-+++ b/arch/alpha/Kconfig
-@@ -698,6 +698,33 @@ config HZ
- default 1200 if HZ_1200
- default 1024
-
-+config ALPHA_UAC_SYSCTL
-+ bool "Configure UAC policy via sysctl"
-+ depends on SYSCTL
-+ default y
-+ ---help---
-+ Configuring the UAC (unaligned access control) policy on a Linux
-+ system usually involves setting a compile time define. If you say
-+ Y here, you will be able to modify the UAC policy at runtime using
-+ the /proc interface.
-+
-+ The UAC policy defines the action Linux should take when an
-+ unaligned memory access occurs. The action can include printing a
-+ warning message (NOPRINT), sending a signal to the offending
-+ program to help developers debug their applications (SIGBUS), or
-+ disabling the transparent fixing (NOFIX).
-+
-+ The sysctls will be initialized to the compile-time defined UAC
-+ policy. You can change these manually, or with the sysctl(8)
-+ userspace utility.
-+
-+ To disable the warning messages at runtime, you would use
-+
-+ echo 1 > /proc/sys/kernel/uac/noprint
-+
-+ This is pretty harmless. Say Y if you're not sure.
-+
-+
- source "drivers/pci/Kconfig"
- source "drivers/eisa/Kconfig"
-
-diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
-index f43bd05dede2..fb2dc5a0164b 100644
---- a/arch/alpha/kernel/traps.c
-+++ b/arch/alpha/kernel/traps.c
-@@ -105,6 +105,49 @@ static char * ireg_name[] = {"v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6",
- "t10", "t11", "ra", "pv", "at", "gp", "sp", "zero"};
- #endif
-
-+#ifdef CONFIG_ALPHA_UAC_SYSCTL
-+
-+#include <linux/sysctl.h>
-+
-+static int enabled_noprint = 0;
-+static int enabled_sigbus = 0;
-+static int enabled_nofix = 0;
-+
-+struct ctl_table uac_table[] = {
-+ {
-+ .procname = "noprint",
-+ .data = &enabled_noprint,
-+ .maxlen = sizeof (int),
-+ .mode = 0644,
-+ .proc_handler = &proc_dointvec,
-+ },
-+ {
-+ .procname = "sigbus",
-+ .data = &enabled_sigbus,
-+ .maxlen = sizeof (int),
-+ .mode = 0644,
-+ .proc_handler = &proc_dointvec,
-+ },
-+ {
-+ .procname = "nofix",
-+ .data = &enabled_nofix,
-+ .maxlen = sizeof (int),
-+ .mode = 0644,
-+ .proc_handler = &proc_dointvec,
-+ },
-+ { }
-+};
-+
-+static int __init init_uac_sysctl(void)
-+{
-+ /* Initialize sysctls with the #defined UAC policy */
-+ enabled_noprint = (test_thread_flag (TS_UAC_NOPRINT)) ? 1 : 0;
-+ enabled_sigbus = (test_thread_flag (TS_UAC_SIGBUS)) ? 1 : 0;
-+ enabled_nofix = (test_thread_flag (TS_UAC_NOFIX)) ? 1 : 0;
-+ return 0;
-+}
-+#endif
-+
- static void
- dik_show_code(unsigned int *pc)
- {
-@@ -764,7 +807,12 @@ do_entUnaUser(void __user * va, unsigned long opcode,
- /* Check the UAC bits to decide what the user wants us to do
- with the unaliged access. */
-
-+#ifndef CONFIG_ALPHA_UAC_SYSCTL
- if (!(current_thread_info()->status & TS_UAC_NOPRINT)) {
-+#else /* CONFIG_ALPHA_UAC_SYSCTL */
-+ if (!(current_thread_info()->status & TS_UAC_NOPRINT) &&
-+ !(enabled_noprint)) {
-+#endif /* CONFIG_ALPHA_UAC_SYSCTL */
- if (__ratelimit(&ratelimit)) {
- printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n",
- current->comm, task_pid_nr(current),
-@@ -1031,3 +1079,6 @@ trap_init(void)
- wrent(entSys, 5);
- wrent(entDbg, 6);
- }
-+#ifdef CONFIG_ALPHA_UAC_SYSCTL
-+ __initcall(init_uac_sysctl);
-+#endif
-diff --git a/kernel/sysctl.c b/kernel/sysctl.c
-index c2f4f6b34206..c6eca30b5c7b 100644
---- a/kernel/sysctl.c
-+++ b/kernel/sysctl.c
-@@ -157,6 +157,11 @@ extern char fbcon_decor_path[];
- #ifdef CONFIG_INOTIFY_USER
- #include <linux/inotify.h>
- #endif
-+
-+#ifdef CONFIG_ALPHA_UAC_SYSCTL
-+extern struct ctl_table uac_table[];
-+#endif
-+
- #ifdef CONFIG_SPARC
- #endif
-
-@@ -1875,6 +1880,13 @@ static struct ctl_table debug_table[] = {
- .extra2 = &one,
- },
- #endif
-+#ifdef CONFIG_ALPHA_UAC_SYSCTL
-+ {
-+ .procname = "uac",
-+ .mode = 0555,
-+ .child = uac_table,
-+ },
-+#endif /* CONFIG_ALPHA_UAC_SYSCTL */
- { }
- };
-
diff --git a/sys-kernel/boest-v4.16.18/0015-4.16-4567_distro-Gentoo-Kconfig.patch.patch b/sys-kernel/boest-v4.16.18/0015-4.16-4567_distro-Gentoo-Kconfig.patch.patch
deleted file mode 100644
index 6e266325..00000000
--- a/sys-kernel/boest-v4.16.18/0015-4.16-4567_distro-Gentoo-Kconfig.patch.patch
+++ /dev/null
@@ -1,172 +0,0 @@
-From b63ca4ba872b661106b6bd5852e0b82eb25d714c Mon Sep 17 00:00:00 2001
-From: Mike Pagano <mpagano@gentoo.org>
-Date: Thu, 2 Mar 2017 11:16:08 -0500
-Subject: [PATCH 15/16] 4.16:4567_distro-Gentoo-Kconfig.patch
-
----
- Kconfig | 2 +
- distro/Kconfig | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 147 insertions(+)
-
-diff --git a/Kconfig b/Kconfig
-index 8c4c1cb0f9cd..ccce41660d28 100644
---- a/Kconfig
-+++ b/Kconfig
-@@ -9,4 +9,6 @@ config SRCARCH
- string
- option env="SRCARCH"
-
-+source "distro/Kconfig"
-+
- source "arch/$SRCARCH/Kconfig"
-diff --git a/distro/Kconfig b/distro/Kconfig
-new file mode 100644
-index 000000000000..e56515144fed
---- /dev/null
-+++ b/distro/Kconfig
-@@ -0,0 +1,145 @@
-+menu "Gentoo Linux"
-+
-+config GENTOO_LINUX
-+ bool "Gentoo Linux support"
-+
-+ default y
-+
-+ help
-+ In order to boot Gentoo Linux a minimal set of config settings needs to
-+ be enabled in the kernel; to avoid the users from having to enable them
-+ manually as part of a Gentoo Linux installation or a new clean config,
-+ we enable these config settings by default for convenience.
-+
-+ See the settings that become available for more details and fine-tuning.
-+
-+config GENTOO_LINUX_UDEV
-+ bool "Linux dynamic and persistent device naming (userspace devfs) support"
-+
-+ depends on GENTOO_LINUX
-+ default y if GENTOO_LINUX
-+
-+ select DEVTMPFS
-+ select TMPFS
-+ select UNIX
-+
-+ select MMU
-+ select SHMEM
-+
-+ help
-+ In order to boot Gentoo Linux a minimal set of config settings needs to
-+ be enabled in the kernel; to avoid the users from having to enable them
-+ manually as part of a Gentoo Linux installation or a new clean config,
-+ we enable these config settings by default for convenience.
-+
-+ Currently this only selects TMPFS, DEVTMPFS and their dependencies.
-+ TMPFS is enabled to maintain a tmpfs file system at /dev/shm, /run and
-+ /sys/fs/cgroup; DEVTMPFS to maintain a devtmpfs file system at /dev.
-+
-+ Some of these are critical files that need to be available early in the
-+ boot process; if not available, it causes sysfs and udev to malfunction.
-+
-+ To ensure Gentoo Linux boots, it is best to leave this setting enabled;
-+ if you run a custom setup, you could consider whether to disable this.
-+
-+config GENTOO_LINUX_PORTAGE
-+ bool "Select options required by Portage features"
-+
-+ depends on GENTOO_LINUX
-+ default y if GENTOO_LINUX
-+
-+ select CGROUPS
-+ select NAMESPACES
-+ select IPC_NS
-+ select NET_NS
-+ select SYSVIPC
-+
-+ help
-+ This enables options required by various Portage FEATURES.
-+ Currently this selects:
-+
-+ CGROUPS (required for FEATURES=cgroup)
-+ IPC_NS (required for FEATURES=ipc-sandbox)
-+ NET_NS (required for FEATURES=network-sandbox)
-+ SYSVIPC (required by IPC_NS)
-+
-+
-+ It is highly recommended that you leave this enabled as these FEATURES
-+ are, or will soon be, enabled by default.
-+
-+menu "Support for init systems, system and service managers"
-+ visible if GENTOO_LINUX
-+
-+config GENTOO_LINUX_INIT_SCRIPT
-+ bool "OpenRC, runit and other script based systems and managers"
-+
-+ default y if GENTOO_LINUX
-+
-+ depends on GENTOO_LINUX
-+
-+ select BINFMT_SCRIPT
-+
-+ help
-+ The init system is the first thing that loads after the kernel booted.
-+
-+ These config settings allow you to select which init systems to support;
-+ instead of having to select all the individual settings all over the
-+ place, these settings allows you to select all the settings at once.
-+
-+ This particular setting enables all the known requirements for OpenRC,
-+ runit and similar script based systems and managers.
-+
-+ If you are unsure about this, it is best to leave this setting enabled.
-+
-+config GENTOO_LINUX_INIT_SYSTEMD
-+ bool "systemd"
-+
-+ default n
-+
-+ depends on GENTOO_LINUX && GENTOO_LINUX_UDEV
-+
-+ select AUTOFS4_FS
-+ select BLK_DEV_BSG
-+ select CGROUPS
-+ select CHECKPOINT_RESTORE
-+ select CRYPTO_HMAC
-+ select CRYPTO_SHA256
-+ select CRYPTO_USER_API_HASH
-+ select DEVPTS_MULTIPLE_INSTANCES
-+ select DMIID if X86_32 || X86_64 || X86
-+ select EPOLL
-+ select FANOTIFY
-+ select FHANDLE
-+ select INOTIFY_USER
-+ select IPV6
-+ select NET
-+ select NET_NS
-+ select PROC_FS
-+ select SECCOMP
-+ select SECCOMP_FILTER
-+ select SIGNALFD
-+ select SYSFS
-+ select TIMERFD
-+ select TMPFS_POSIX_ACL
-+ select TMPFS_XATTR
-+
-+ select ANON_INODES
-+ select BLOCK
-+ select EVENTFD
-+ select FSNOTIFY
-+ select INET
-+ select NLATTR
-+
-+ help
-+ The init system is the first thing that loads after the kernel booted.
-+
-+ These config settings allow you to select which init systems to support;
-+ instead of having to select all the individual settings all over the
-+ place, these settings allows you to select all the settings at once.
-+
-+ This particular setting enables all the known requirements for systemd;
-+ it also enables suggested optional settings, as the package suggests to.
-+
-+endmenu
-+
-+endmenu
diff --git a/sys-kernel/boest-v4.16.18/0016-WARNING.patch b/sys-kernel/boest-v4.16.18/0016-WARNING.patch
deleted file mode 100644
index 50dbd19c..00000000
--- a/sys-kernel/boest-v4.16.18/0016-WARNING.patch
+++ /dev/null
@@ -1,550 +0,0 @@
-From e84636349dca506803d1ee6500bf313c60c6524c Mon Sep 17 00:00:00 2001
-From: Mike Pagano <mpagano@gentoo.org>
-Date: Fri, 9 Mar 2018 14:24:47 -0500
-Subject: [PATCH 16/16] WARNING This patch works with gcc versions 4.9+ and
- with kernel version 3.15+ and should NOT be applied when compiling on older
- versions of gcc due to key name changes of the march flags introduced with
- the version 4.9 release of gcc.[1]
-
-Use the older version of this patch hosted on the same github for older
-versions of gcc.
-
-FEATURES
-This patch adds additional CPU options to the Linux kernel accessible under:
- Processor type and features --->
- Processor family --->
-
-The expanded microarchitectures include:
-* AMD Improved K8-family
-* AMD K10-family
-* AMD Family 10h (Barcelona)
-* AMD Family 14h (Bobcat)
-* AMD Family 16h (Jaguar)
-* AMD Family 15h (Bulldozer)
-* AMD Family 15h (Piledriver)
-* AMD Family 15h (Steamroller)
-* AMD Family 15h (Excavator)
-* AMD Family 17h (Zen)
-* Intel Silvermont low-power processors
-* Intel 1st Gen Core i3/i5/i7 (Nehalem)
-* Intel 1.5 Gen Core i3/i5/i7 (Westmere)
-* Intel 2nd Gen Core i3/i5/i7 (Sandybridge)
-* Intel 3rd Gen Core i3/i5/i7 (Ivybridge)
-* Intel 4th Gen Core i3/i5/i7 (Haswell)
-* Intel 5th Gen Core i3/i5/i7 (Broadwell)
-* Intel 6th Gen Core i3/i5.i7 (Skylake)
-
-It also offers to compile passing the 'native' option which, "selects the CPU
-to generate code for at compilation time by determining the processor type of
-the compiling machine. Using -march=native enables all instruction subsets
-supported by the local machine and will produce code optimized for the local
-machine under the constraints of the selected instruction set."[3]
-
-MINOR NOTES
-This patch also changes 'atom' to 'bonnell' in accordance with the gcc v4.9
-changes. Note that upstream is using the deprecated 'match=atom' flags when I
-believe it should use the newer 'march=bonnell' flag for atom processors.[2]
-
-It is not recommended to compile on Atom-CPUs with the 'native' option.[4] The
-recommendation is to use the 'atom' option instead.
-
-BENEFITS
-Small but real speed increases are measurable using a make endpoint comparing
-a generic kernel to one built with one of the respective microarchs.
-
-See the following experimental evidence supporting this statement:
-https://github.com/graysky2/kernel_gcc_patch
-
-REQUIREMENTS
-linux version >=3.15
-gcc version >=4.9
-
-ACKNOWLEDGMENTS
-This patch builds on the seminal work by Jeroen.[5]
-
-REFERENCES
-1. https://gcc.gnu.org/gcc-4.9/changes.html
-2. https://bugzilla.kernel.org/show_bug.cgi?id=77461
-3. https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html
-4. https://github.com/graysky2/kernel_gcc_patch/issues/15
-5. http://www.linuxforge.net/docs/linux/linux-gcc.php
----
- arch/x86/Kconfig.cpu | 226 ++++++++++++++++++++++++++++++++++++------
- arch/x86/Makefile | 33 +++++-
- arch/x86/Makefile_32.cpu | 23 ++++-
- arch/x86/include/asm/module.h | 38 +++++++
- 4 files changed, 283 insertions(+), 37 deletions(-)
-
-diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
-index 638411f22267..e6bcfcfa7efc 100644
---- a/arch/x86/Kconfig.cpu
-+++ b/arch/x86/Kconfig.cpu
-@@ -116,6 +116,7 @@ config MPENTIUMM
- config MPENTIUM4
- bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/older Xeon"
- depends on X86_32
-+ select X86_P6_NOP
- ---help---
- Select this for Intel Pentium 4 chips. This includes the
- Pentium 4, Pentium D, P4-based Celeron and Xeon, and
-@@ -148,9 +149,8 @@ config MPENTIUM4
- -Paxville
- -Dempsey
-
--
- config MK6
-- bool "K6/K6-II/K6-III"
-+ bool "AMD K6/K6-II/K6-III"
- depends on X86_32
- ---help---
- Select this for an AMD K6-family processor. Enables use of
-@@ -158,7 +158,7 @@ config MK6
- flags to GCC.
-
- config MK7
-- bool "Athlon/Duron/K7"
-+ bool "AMD Athlon/Duron/K7"
- depends on X86_32
- ---help---
- Select this for an AMD Athlon K7-family processor. Enables use of
-@@ -166,12 +166,83 @@ config MK7
- flags to GCC.
-
- config MK8
-- bool "Opteron/Athlon64/Hammer/K8"
-+ bool "AMD Opteron/Athlon64/Hammer/K8"
- ---help---
- Select this for an AMD Opteron or Athlon64 Hammer-family processor.
- Enables use of some extended instructions, and passes appropriate
- optimization flags to GCC.
-
-+config MK8SSE3
-+ bool "AMD Opteron/Athlon64/Hammer/K8 with SSE3"
-+ ---help---
-+ Select this for improved AMD Opteron or Athlon64 Hammer-family processors.
-+ Enables use of some extended instructions, and passes appropriate
-+ optimization flags to GCC.
-+
-+config MK10
-+ bool "AMD 61xx/7x50/PhenomX3/X4/II/K10"
-+ ---help---
-+ Select this for an AMD 61xx Eight-Core Magny-Cours, Athlon X2 7x50,
-+ Phenom X3/X4/II, Athlon II X2/X3/X4, or Turion II-family processor.
-+ Enables use of some extended instructions, and passes appropriate
-+ optimization flags to GCC.
-+
-+config MBARCELONA
-+ bool "AMD Barcelona"
-+ ---help---
-+ Select this for AMD Family 10h Barcelona processors.
-+
-+ Enables -march=barcelona
-+
-+config MBOBCAT
-+ bool "AMD Bobcat"
-+ ---help---
-+ Select this for AMD Family 14h Bobcat processors.
-+
-+ Enables -march=btver1
-+
-+config MJAGUAR
-+ bool "AMD Jaguar"
-+ ---help---
-+ Select this for AMD Family 16h Jaguar processors.
-+
-+ Enables -march=btver2
-+
-+config MBULLDOZER
-+ bool "AMD Bulldozer"
-+ ---help---
-+ Select this for AMD Family 15h Bulldozer processors.
-+
-+ Enables -march=bdver1
-+
-+config MPILEDRIVER
-+ bool "AMD Piledriver"
-+ ---help---
-+ Select this for AMD Family 15h Piledriver processors.
-+
-+ Enables -march=bdver2
-+
-+config MSTEAMROLLER
-+ bool "AMD Steamroller"
-+ ---help---
-+ Select this for AMD Family 15h Steamroller processors.
-+
-+ Enables -march=bdver3
-+
-+config MEXCAVATOR
-+ bool "AMD Excavator"
-+ ---help---
-+ Select this for AMD Family 15h Excavator processors.
-+
-+ Enables -march=bdver4
-+
-+config MZEN
-+ bool "AMD Zen"
-+ ---help---
-+ Select this for AMD Family 17h Zen processors.
-+
-+ Enables -march=znver1
-+
- config MCRUSOE
- bool "Crusoe"
- depends on X86_32
-@@ -253,6 +324,7 @@ config MVIAC7
-
- config MPSC
- bool "Intel P4 / older Netburst based Xeon"
-+ select X86_P6_NOP
- depends on X86_64
- ---help---
- Optimize for Intel Pentium 4, Pentium D and older Nocona/Dempsey
-@@ -262,17 +334,9 @@ config MPSC
- using the cpu family field
- in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one.
-
--config MCORE2
-- bool "Core 2/newer Xeon"
-- ---help---
--
-- Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and
-- 53xx) CPUs. You can distinguish newer from older Xeons by the CPU
-- family in /proc/cpuinfo. Newer ones have 6 and older ones 15
-- (not a typo)
--
- config MATOM
- bool "Intel Atom"
-+ select X86_P6_NOP
- ---help---
-
- Select this for the Intel Atom platform. Intel Atom CPUs have an
-@@ -280,6 +344,90 @@ config MATOM
- accordingly optimized code. Use a recent GCC with specific Atom
- support in order to fully benefit from selecting this option.
-
-+config MCORE2
-+ bool "Intel Core 2"
-+ select X86_P6_NOP
-+ ---help---
-+
-+ Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and
-+ 53xx) CPUs. You can distinguish newer from older Xeons by the CPU
-+ family in /proc/cpuinfo. Newer ones have 6 and older ones 15
-+ (not a typo)
-+
-+ Enables -march=core2
-+
-+config MNEHALEM
-+ bool "Intel Nehalem"
-+ select X86_P6_NOP
-+ ---help---
-+
-+ Select this for 1st Gen Core processors in the Nehalem family.
-+
-+ Enables -march=nehalem
-+
-+config MWESTMERE
-+ bool "Intel Westmere"
-+ select X86_P6_NOP
-+ ---help---
-+
-+ Select this for the Intel Westmere formerly Nehalem-C family.
-+
-+ Enables -march=westmere
-+
-+config MSILVERMONT
-+ bool "Intel Silvermont"
-+ select X86_P6_NOP
-+ ---help---
-+
-+ Select this for the Intel Silvermont platform.
-+
-+ Enables -march=silvermont
-+
-+config MSANDYBRIDGE
-+ bool "Intel Sandy Bridge"
-+ select X86_P6_NOP
-+ ---help---
-+
-+ Select this for 2nd Gen Core processors in the Sandy Bridge family.
-+
-+ Enables -march=sandybridge
-+
-+config MIVYBRIDGE
-+ bool "Intel Ivy Bridge"
-+ select X86_P6_NOP
-+ ---help---
-+
-+ Select this for 3rd Gen Core processors in the Ivy Bridge family.
-+
-+ Enables -march=ivybridge
-+
-+config MHASWELL
-+ bool "Intel Haswell"
-+ select X86_P6_NOP
-+ ---help---
-+
-+ Select this for 4th Gen Core processors in the Haswell family.
-+
-+ Enables -march=haswell
-+
-+config MBROADWELL
-+ bool "Intel Broadwell"
-+ select X86_P6_NOP
-+ ---help---
-+
-+ Select this for 5th Gen Core processors in the Broadwell family.
-+
-+ Enables -march=broadwell
-+
-+config MSKYLAKE
-+ bool "Intel Skylake"
-+ select X86_P6_NOP
-+ ---help---
-+
-+ Select this for 6th Gen Core processors in the Skylake family.
-+
-+ Enables -march=skylake
-+
- config GENERIC_CPU
- bool "Generic-x86-64"
- depends on X86_64
-@@ -287,6 +435,19 @@ config GENERIC_CPU
- Generic x86-64 CPU.
- Run equally well on all x86-64 CPUs.
-
-+config MNATIVE
-+ bool "Native optimizations autodetected by GCC"
-+ ---help---
-+
-+ GCC 4.2 and above support -march=native, which automatically detects
-+ the optimum settings to use based on your processor. -march=native
-+ also detects and applies additional settings beyond -march specific
-+ to your CPU, (eg. -msse4). Unless you have a specific reason not to
-+ (e.g. distcc cross-compiling), you should probably be using
-+ -march=native rather than anything listed below.
-+
-+ Enables -march=native
-+
- endchoice
-
- config X86_GENERIC
-@@ -311,7 +472,7 @@ config X86_INTERNODE_CACHE_SHIFT
- config X86_L1_CACHE_SHIFT
- int
- default "7" if MPENTIUM4 || MPSC
-- default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
-+ default "6" if MK7 || MK8 || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MJAGUAR || MPENTIUMM || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MNATIVE || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
- default "4" if MELAN || M486 || MGEODEGX1
- default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
-
-@@ -329,35 +490,36 @@ config X86_ALIGNMENT_16
-
- config X86_INTEL_USERCOPY
- def_bool y
-- depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2
-+ depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK8SSE3 || MK7 || MEFFICEON || MCORE2 || MK10 || MBARCELONA || MNEHALEM || MWESTMERE || MSILVERMONT || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MNATIVE
-
- config X86_USE_PPRO_CHECKSUM
- def_bool y
-- depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM
-+ depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MK10 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MK8SSE3 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MATOM || MNATIVE
-
- config X86_USE_3DNOW
- def_bool y
- depends on (MCYRIXIII || MK7 || MGEODE_LX) && !UML
-
--#
--# P6_NOPs are a relatively minor optimization that require a family >=
--# 6 processor, except that it is broken on certain VIA chips.
--# Furthermore, AMD chips prefer a totally different sequence of NOPs
--# (which work on all CPUs). In addition, it looks like Virtual PC
--# does not understand them.
--#
--# As a result, disallow these if we're not compiling for X86_64 (these
--# NOPs do work on all x86-64 capable chips); the list of processors in
--# the right-hand clause are the cores that benefit from this optimization.
--#
- config X86_P6_NOP
-- def_bool y
-- depends on X86_64
-- depends on (MCORE2 || MPENTIUM4 || MPSC)
-+ default n
-+ bool "Support for P6_NOPs on Intel chips"
-+ depends on (MCORE2 || MPENTIUM4 || MPSC || MATOM || MNEHALEM || MWESTMERE || MSILVERMONT || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MNATIVE)
-+ ---help---
-+ P6_NOPs are a relatively minor optimization that require a family >=
-+ 6 processor, except that it is broken on certain VIA chips.
-+ Furthermore, AMD chips prefer a totally different sequence of NOPs
-+ (which work on all CPUs). In addition, it looks like Virtual PC
-+ does not understand them.
-+
-+ As a result, disallow these if we're not compiling for X86_64 (these
-+ NOPs do work on all x86-64 capable chips); the list of processors in
-+ the right-hand clause are the cores that benefit from this optimization.
-+
-+ Say Y if you have Intel CPU newer than Pentium Pro, N otherwise.
-
- config X86_TSC
- def_bool y
-- depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) || X86_64
-+ depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MK8SSE3 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MNATIVE || MATOM) || X86_64
-
- config X86_CMPXCHG64
- def_bool y
-@@ -367,7 +529,7 @@ config X86_CMPXCHG64
- # generates cmov.
- config X86_CMOV
- def_bool y
-- depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX)
-+ depends on (MK8 || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MEXCAVATOR || MZEN || MJAGUAR || MK7 || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MNATIVE || MATOM || MGEODE_LX)
-
- config X86_MINIMUM_CPU_FAMILY
- int
-diff --git a/arch/x86/Makefile b/arch/x86/Makefile
-index 1c4d012550ec..5562202423db 100644
---- a/arch/x86/Makefile
-+++ b/arch/x86/Makefile
-@@ -124,13 +124,40 @@ else
- KBUILD_CFLAGS += $(call cc-option,-mskip-rax-setup)
-
- # FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu)
-+ cflags-$(CONFIG_MNATIVE) += $(call cc-option,-march=native)
- cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8)
-+ cflags-$(CONFIG_MK8SSE3) += $(call cc-option,-march=k8-sse3,-mtune=k8)
-+ cflags-$(CONFIG_MK10) += $(call cc-option,-march=amdfam10)
-+ cflags-$(CONFIG_MBARCELONA) += $(call cc-option,-march=barcelona)
-+ cflags-$(CONFIG_MBOBCAT) += $(call cc-option,-march=btver1)
-+ cflags-$(CONFIG_MJAGUAR) += $(call cc-option,-march=btver2)
-+ cflags-$(CONFIG_MBULLDOZER) += $(call cc-option,-march=bdver1)
-+ cflags-$(CONFIG_MPILEDRIVER) += $(call cc-option,-march=bdver2)
-+ cflags-$(CONFIG_MSTEAMROLLER) += $(call cc-option,-march=bdver3)
-+ cflags-$(CONFIG_MEXCAVATOR) += $(call cc-option,-march=bdver4)
-+ cflags-$(CONFIG_MZEN) += $(call cc-option,-march=znver1)
- cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona)
-
- cflags-$(CONFIG_MCORE2) += \
-- $(call cc-option,-march=core2,$(call cc-option,-mtune=generic))
-- cflags-$(CONFIG_MATOM) += $(call cc-option,-march=atom) \
-- $(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic))
-+ $(call cc-option,-march=core2,$(call cc-option,-mtune=core2))
-+ cflags-$(CONFIG_MNEHALEM) += \
-+ $(call cc-option,-march=nehalem,$(call cc-option,-mtune=nehalem))
-+ cflags-$(CONFIG_MWESTMERE) += \
-+ $(call cc-option,-march=westmere,$(call cc-option,-mtune=westmere))
-+ cflags-$(CONFIG_MSILVERMONT) += \
-+ $(call cc-option,-march=silvermont,$(call cc-option,-mtune=silvermont))
-+ cflags-$(CONFIG_MSANDYBRIDGE) += \
-+ $(call cc-option,-march=sandybridge,$(call cc-option,-mtune=sandybridge))
-+ cflags-$(CONFIG_MIVYBRIDGE) += \
-+ $(call cc-option,-march=ivybridge,$(call cc-option,-mtune=ivybridge))
-+ cflags-$(CONFIG_MHASWELL) += \
-+ $(call cc-option,-march=haswell,$(call cc-option,-mtune=haswell))
-+ cflags-$(CONFIG_MBROADWELL) += \
-+ $(call cc-option,-march=broadwell,$(call cc-option,-mtune=broadwell))
-+ cflags-$(CONFIG_MSKYLAKE) += \
-+ $(call cc-option,-march=skylake,$(call cc-option,-mtune=skylake))
-+ cflags-$(CONFIG_MATOM) += $(call cc-option,-march=bonnell) \
-+ $(call cc-option,-mtune=bonnell,$(call cc-option,-mtune=generic))
- cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic)
- KBUILD_CFLAGS += $(cflags-y)
-
-diff --git a/arch/x86/Makefile_32.cpu b/arch/x86/Makefile_32.cpu
-index 1f5faf8606b4..a25c0f818b15 100644
---- a/arch/x86/Makefile_32.cpu
-+++ b/arch/x86/Makefile_32.cpu
-@@ -23,7 +23,18 @@ cflags-$(CONFIG_MK6) += -march=k6
- # Please note, that patches that add -march=athlon-xp and friends are pointless.
- # They make zero difference whatsosever to performance at this time.
- cflags-$(CONFIG_MK7) += -march=athlon
-+cflags-$(CONFIG_MNATIVE) += $(call cc-option,-march=native)
- cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8,-march=athlon)
-+cflags-$(CONFIG_MK8SSE3) += $(call cc-option,-march=k8-sse3,-march=athlon)
-+cflags-$(CONFIG_MK10) += $(call cc-option,-march=amdfam10,-march=athlon)
-+cflags-$(CONFIG_MBARCELONA) += $(call cc-option,-march=barcelona,-march=athlon)
-+cflags-$(CONFIG_MBOBCAT) += $(call cc-option,-march=btver1,-march=athlon)
-+cflags-$(CONFIG_MJAGUAR) += $(call cc-option,-march=btver2,-march=athlon)
-+cflags-$(CONFIG_MBULLDOZER) += $(call cc-option,-march=bdver1,-march=athlon)
-+cflags-$(CONFIG_MPILEDRIVER) += $(call cc-option,-march=bdver2,-march=athlon)
-+cflags-$(CONFIG_MSTEAMROLLER) += $(call cc-option,-march=bdver3,-march=athlon)
-+cflags-$(CONFIG_MEXCAVATOR) += $(call cc-option,-march=bdver4,-march=athlon)
-+cflags-$(CONFIG_MZEN) += $(call cc-option,-march=znver1,-march=athlon)
- cflags-$(CONFIG_MCRUSOE) += -march=i686 -falign-functions=0 -falign-jumps=0 -falign-loops=0
- cflags-$(CONFIG_MEFFICEON) += -march=i686 $(call tune,pentium3) -falign-functions=0 -falign-jumps=0 -falign-loops=0
- cflags-$(CONFIG_MWINCHIPC6) += $(call cc-option,-march=winchip-c6,-march=i586)
-@@ -32,8 +43,16 @@ cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) -falign-fu
- cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686)
- cflags-$(CONFIG_MVIAC7) += -march=i686
- cflags-$(CONFIG_MCORE2) += -march=i686 $(call tune,core2)
--cflags-$(CONFIG_MATOM) += $(call cc-option,-march=atom,$(call cc-option,-march=core2,-march=i686)) \
-- $(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic))
-+cflags-$(CONFIG_MNEHALEM) += -march=i686 $(call tune,nehalem)
-+cflags-$(CONFIG_MWESTMERE) += -march=i686 $(call tune,westmere)
-+cflags-$(CONFIG_MSILVERMONT) += -march=i686 $(call tune,silvermont)
-+cflags-$(CONFIG_MSANDYBRIDGE) += -march=i686 $(call tune,sandybridge)
-+cflags-$(CONFIG_MIVYBRIDGE) += -march=i686 $(call tune,ivybridge)
-+cflags-$(CONFIG_MHASWELL) += -march=i686 $(call tune,haswell)
-+cflags-$(CONFIG_MBROADWELL) += -march=i686 $(call tune,broadwell)
-+cflags-$(CONFIG_MSKYLAKE) += -march=i686 $(call tune,skylake)
-+cflags-$(CONFIG_MATOM) += $(call cc-option,-march=bonnell,$(call cc-option,-march=core2,-march=i686)) \
-+ $(call cc-option,-mtune=bonnell,$(call cc-option,-mtune=generic))
-
- # AMD Elan support
- cflags-$(CONFIG_MELAN) += -march=i486
-diff --git a/arch/x86/include/asm/module.h b/arch/x86/include/asm/module.h
-index 7948a17febb4..39c823cfa37e 100644
---- a/arch/x86/include/asm/module.h
-+++ b/arch/x86/include/asm/module.h
-@@ -25,6 +25,24 @@ struct mod_arch_specific {
- #define MODULE_PROC_FAMILY "586MMX "
- #elif defined CONFIG_MCORE2
- #define MODULE_PROC_FAMILY "CORE2 "
-+#elif defined CONFIG_MNATIVE
-+#define MODULE_PROC_FAMILY "NATIVE "
-+#elif defined CONFIG_MNEHALEM
-+#define MODULE_PROC_FAMILY "NEHALEM "
-+#elif defined CONFIG_MWESTMERE
-+#define MODULE_PROC_FAMILY "WESTMERE "
-+#elif defined CONFIG_MSILVERMONT
-+#define MODULE_PROC_FAMILY "SILVERMONT "
-+#elif defined CONFIG_MSANDYBRIDGE
-+#define MODULE_PROC_FAMILY "SANDYBRIDGE "
-+#elif defined CONFIG_MIVYBRIDGE
-+#define MODULE_PROC_FAMILY "IVYBRIDGE "
-+#elif defined CONFIG_MHASWELL
-+#define MODULE_PROC_FAMILY "HASWELL "
-+#elif defined CONFIG_MBROADWELL
-+#define MODULE_PROC_FAMILY "BROADWELL "
-+#elif defined CONFIG_MSKYLAKE
-+#define MODULE_PROC_FAMILY "SKYLAKE "
- #elif defined CONFIG_MATOM
- #define MODULE_PROC_FAMILY "ATOM "
- #elif defined CONFIG_M686
-@@ -43,6 +61,26 @@ struct mod_arch_specific {
- #define MODULE_PROC_FAMILY "K7 "
- #elif defined CONFIG_MK8
- #define MODULE_PROC_FAMILY "K8 "
-+#elif defined CONFIG_MK8SSE3
-+#define MODULE_PROC_FAMILY "K8SSE3 "
-+#elif defined CONFIG_MK10
-+#define MODULE_PROC_FAMILY "K10 "
-+#elif defined CONFIG_MBARCELONA
-+#define MODULE_PROC_FAMILY "BARCELONA "
-+#elif defined CONFIG_MBOBCAT
-+#define MODULE_PROC_FAMILY "BOBCAT "
-+#elif defined CONFIG_MBULLDOZER
-+#define MODULE_PROC_FAMILY "BULLDOZER "
-+#elif defined CONFIG_MPILEDRIVER
-+#define MODULE_PROC_FAMILY "PILEDRIVER "
-+#elif defined CONFIG_MSTEAMROLLER
-+#define MODULE_PROC_FAMILY "STEAMROLLER "
-+#elif defined CONFIG_MJAGUAR
-+#define MODULE_PROC_FAMILY "JAGUAR "
-+#elif defined CONFIG_MEXCAVATOR
-+#define MODULE_PROC_FAMILY "EXCAVATOR "
-+#elif defined CONFIG_MZEN
-+#define MODULE_PROC_FAMILY "ZEN "
- #elif defined CONFIG_MELAN
- #define MODULE_PROC_FAMILY "ELAN "
- #elif defined CONFIG_MCRUSOE
diff --git a/sys-kernel/stable-sources-4.16.18 b/sys-kernel/stable-sources-4.16.18
deleted file mode 120000
index 7e6815cc..00000000
--- a/sys-kernel/stable-sources-4.16.18
+++ /dev/null
@@ -1 +0,0 @@
-boest-v4.16.18 \ No newline at end of file