diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2013-03-09 15:03:47 -0500 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2013-03-09 15:03:47 -0500 |
commit | 45ffc43f0be9979ec987f6938aff51f44617d8f3 (patch) | |
tree | 68b03d79fdc6eeb52769e1a6fdc6a1ce2fbb0ded | |
parent | Correct 3.8.2, add bump from 3.8.1 (diff) | |
download | hardened-patchset-45ffc43f0be9979ec987f6938aff51f44617d8f3.tar.gz hardened-patchset-45ffc43f0be9979ec987f6938aff51f44617d8f3.tar.bz2 hardened-patchset-45ffc43f0be9979ec987f6938aff51f44617d8f3.zip |
Grsec/PaX: 2.9.1-{2.6.32.60,3.2.40,3.8.2}-20130308221520130308
-rw-r--r-- | 2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201303082034.patch (renamed from 2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201303012253.patch) | 109 | ||||
-rw-r--r-- | 3.2.40/0000_README (renamed from 3.2.39/0000_README) | 8 | ||||
-rw-r--r-- | 3.2.40/1021_linux-3.2.22.patch (renamed from 3.2.39/1021_linux-3.2.22.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/1022_linux-3.2.23.patch (renamed from 3.2.39/1022_linux-3.2.23.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/1023_linux-3.2.24.patch (renamed from 3.2.39/1023_linux-3.2.24.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/1024_linux-3.2.25.patch (renamed from 3.2.39/1024_linux-3.2.25.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/1025_linux-3.2.26.patch (renamed from 3.2.39/1025_linux-3.2.26.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/1026_linux-3.2.27.patch (renamed from 3.2.39/1026_linux-3.2.27.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/1027_linux-3.2.28.patch (renamed from 3.2.39/1027_linux-3.2.28.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/1028_linux-3.2.29.patch (renamed from 3.2.39/1028_linux-3.2.29.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/1029_linux-3.2.30.patch (renamed from 3.2.39/1029_linux-3.2.30.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/1030_linux-3.2.31.patch (renamed from 3.2.39/1030_linux-3.2.31.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/1031_linux-3.2.32.patch (renamed from 3.2.39/1031_linux-3.2.32.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/1032_linux-3.2.33.patch (renamed from 3.2.39/1032_linux-3.2.33.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/1033_linux-3.2.34.patch (renamed from 3.2.39/1033_linux-3.2.34.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/1034_linux-3.2.35.patch (renamed from 3.2.39/1034_linux-3.2.35.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/1035_linux-3.2.36.patch (renamed from 3.2.39/1035_linux-3.2.36.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/1036_linux-3.2.37.patch (renamed from 3.2.39/1036_linux-3.2.37.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/1037_linux-3.2.38.patch (renamed from 3.2.39/1037_linux-3.2.38.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/1038_linux-3.2.39.patch (renamed from 3.2.39/1039_linux-3.2.39.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/1039_linux-3.2.40.patch | 6295 | ||||
-rw-r--r-- | 3.2.40/4420_grsecurity-2.9.1-3.2.40-201303082037.patch (renamed from 3.2.39/4420_grsecurity-2.9.1-3.2.39-201303012254.patch) | 583 | ||||
-rw-r--r-- | 3.2.40/4425_grsec_remove_EI_PAX.patch (renamed from 3.2.39/4425_grsec_remove_EI_PAX.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/4430_grsec-remove-localversion-grsec.patch (renamed from 3.2.39/4430_grsec-remove-localversion-grsec.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/4435_grsec-mute-warnings.patch (renamed from 3.2.39/4435_grsec-mute-warnings.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/4440_grsec-remove-protected-paths.patch (renamed from 3.2.39/4440_grsec-remove-protected-paths.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/4450_grsec-kconfig-default-gids.patch (renamed from 3.2.39/4450_grsec-kconfig-default-gids.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/4465_selinux-avc_audit-log-curr_ip.patch (renamed from 3.2.39/4465_selinux-avc_audit-log-curr_ip.patch) | 0 | ||||
-rw-r--r-- | 3.2.40/4470_disable-compat_vdso.patch (renamed from 3.2.39/4470_disable-compat_vdso.patch) | 0 | ||||
-rw-r--r-- | 3.8.2/0000_README | 2 | ||||
-rw-r--r-- | 3.8.2/4420_grsecurity-2.9.1-3.8.2-201303082215.patch (renamed from 3.8.2/4420_grsecurity-2.9.1-3.8.2-201303041742.patch) | 5934 |
31 files changed, 12327 insertions, 604 deletions
diff --git a/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201303012253.patch b/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201303082034.patch index ee59351..0660165 100644 --- a/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201303012253.patch +++ b/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201303082034.patch @@ -43702,6 +43702,34 @@ index 6351a26..999af95 100644 if (!perm) { ret = -EPERM; goto reterr; +diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c +index 6069790..33c174a 100644 +--- a/drivers/connector/cn_proc.c ++++ b/drivers/connector/cn_proc.c +@@ -236,7 +236,13 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, + if (msg->len != sizeof(*mc_op)) + return; + +- mc_op = (enum proc_cn_mcast_op*)msg->data; ++ /* Can only change if privileged. */ ++ if (!capable(CAP_NET_ADMIN)) { ++ err = EPERM; ++ goto out; ++ } ++ ++ mc_op = (enum proc_cn_mcast_op *)msg->data; + switch (*mc_op) { + case PROC_CN_MCAST_LISTEN: + atomic_inc(&proc_event_num_listeners); +@@ -248,6 +254,8 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, + err = EINVAL; + break; + } ++ ++out: + cn_proc_ack(err, msg->seq, msg->ack); + } + diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index c7ae026..1769c1d 100644 --- a/drivers/cpufreq/cpufreq.c @@ -114326,6 +114354,18 @@ index 34dcc79..f51ed45 100644 break; default: return -ENOPROTOOPT; +diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c +index 5df7b54..af2376e 100644 +--- a/net/decnet/af_decnet.c ++++ b/net/decnet/af_decnet.c +@@ -469,6 +469,7 @@ static struct proto dn_proto = { + .sysctl_rmem = sysctl_decnet_rmem, + .max_header = DN_MAX_NSP_DATA_HEADER + 64, + .obj_size = sizeof(struct dn_sock), ++ .slab_flags = SLAB_USERCOPY, + }; + + static struct sock *dn_alloc_sock(struct net *net, struct socket *sock, gfp_t gfp) diff --git a/net/decnet/sysctl_net_decnet.c b/net/decnet/sysctl_net_decnet.c index 2036568..c55883d 100644 --- a/net/decnet/sysctl_net_decnet.c @@ -116049,6 +116089,24 @@ index 811984d..11f59b7 100644 seq_printf(m, "Max data size: %d\n", self->max_data_size); seq_printf(m, "Max header size: %d\n", self->max_header_size); +diff --git a/net/irda/iriap.c b/net/irda/iriap.c +index 35a338b..62102d6 100644 +--- a/net/irda/iriap.c ++++ b/net/irda/iriap.c +@@ -489,8 +489,11 @@ static void iriap_getvaluebyclass_confirm(struct iriap_cb *self, + /* case CS_ISO_8859_9: */ + /* case CS_UNICODE: */ + default: +- IRDA_DEBUG(0, "%s(), charset %s, not supported\n", +- __func__, ias_charset_types[charset]); ++ IRDA_DEBUG(0, "%s(), charset [%d] %s, not supported\n", ++ __func__, charset, ++ charset < ARRAY_SIZE(ias_charset_types) ? ++ ias_charset_types[charset] : ++ "(unknown)"); + + /* Aborting, close connection! */ + iriap_disconnect_request(self); diff --git a/net/irda/irttp.c b/net/irda/irttp.c index 9cb79f9..d35d057 100644 --- a/net/irda/irttp.c @@ -117589,6 +117647,46 @@ index 1f9843e..5e9fd60 100644 SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n"); if (pp->fastreuse && sk->sk_reuse && +diff --git a/net/sctp/ssnmap.c b/net/sctp/ssnmap.c +index 737d330..2e7f089 100644 +--- a/net/sctp/ssnmap.c ++++ b/net/sctp/ssnmap.c +@@ -40,8 +40,6 @@ + #include <net/sctp/sctp.h> + #include <net/sctp/sm.h> + +-#define MAX_KMALLOC_SIZE 131072 +- + static struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in, + __u16 out); + +@@ -64,7 +62,7 @@ struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, + int size; + + size = sctp_ssnmap_size(in, out); +- if (size <= MAX_KMALLOC_SIZE) ++ if (size <= KMALLOC_MAX_SIZE) + retval = kmalloc(size, gfp); + else + retval = (struct sctp_ssnmap *) +@@ -81,7 +79,7 @@ struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, + return retval; + + fail_map: +- if (size <= MAX_KMALLOC_SIZE) ++ if (size <= KMALLOC_MAX_SIZE) + kfree(retval); + else + free_pages((unsigned long)retval, get_order(size)); +@@ -123,7 +121,7 @@ void sctp_ssnmap_free(struct sctp_ssnmap *map) + int size; + + size = sctp_ssnmap_size(map->in.len, map->out.len); +- if (size <= MAX_KMALLOC_SIZE) ++ if (size <= KMALLOC_MAX_SIZE) + kfree(map); + else + free_pages((unsigned long)map, get_order(size)); diff --git a/net/sctp/transport.c b/net/sctp/transport.c index e04c9f8..51bc18e 100644 --- a/net/sctp/transport.c @@ -119941,9 +120039,18 @@ index e031952..c9a535d 100644 buflen -= tmp; diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c -index 931cfda..e71808a 100644 +index 931cfda..01983fb 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c +@@ -56,7 +56,7 @@ int install_user_keyrings(void) + + kenter("%p{%u}", user, user->uid); + +- if (user->uid_keyring) { ++ if (user->uid_keyring && user->session_keyring) { + kleave(" = 0 [exist]"); + return 0; + } @@ -208,7 +208,7 @@ static int install_process_keyring(void) ret = install_process_keyring_to_cred(new); if (ret < 0) { diff --git a/3.2.39/0000_README b/3.2.40/0000_README index 2831c66..fd368e5 100644 --- a/3.2.39/0000_README +++ b/3.2.40/0000_README @@ -70,11 +70,15 @@ Patch: 1037_linux-3.2.38.patch From: http://www.kernel.org Desc: Linux 3.2.38 -Patch: 1039_linux-3.2.39.patch +Patch: 1038_linux-3.2.39.patch From: http://www.kernel.org Desc: Linux 3.2.39 -Patch: 4420_grsecurity-2.9.1-3.2.39-201303012254.patch +Patch: 1039_linux-3.2.40.patch +From: http://www.kernel.org +Desc: Linux 3.2.40 + +Patch: 4420_grsecurity-2.9.1-3.2.40-201303082037.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.2.39/1021_linux-3.2.22.patch b/3.2.40/1021_linux-3.2.22.patch index e6ad93a..e6ad93a 100644 --- a/3.2.39/1021_linux-3.2.22.patch +++ b/3.2.40/1021_linux-3.2.22.patch diff --git a/3.2.39/1022_linux-3.2.23.patch b/3.2.40/1022_linux-3.2.23.patch index 3d796d0..3d796d0 100644 --- a/3.2.39/1022_linux-3.2.23.patch +++ b/3.2.40/1022_linux-3.2.23.patch diff --git a/3.2.39/1023_linux-3.2.24.patch b/3.2.40/1023_linux-3.2.24.patch index 4692eb4..4692eb4 100644 --- a/3.2.39/1023_linux-3.2.24.patch +++ b/3.2.40/1023_linux-3.2.24.patch diff --git a/3.2.39/1024_linux-3.2.25.patch b/3.2.40/1024_linux-3.2.25.patch index e95c213..e95c213 100644 --- a/3.2.39/1024_linux-3.2.25.patch +++ b/3.2.40/1024_linux-3.2.25.patch diff --git a/3.2.39/1025_linux-3.2.26.patch b/3.2.40/1025_linux-3.2.26.patch index 44065b9..44065b9 100644 --- a/3.2.39/1025_linux-3.2.26.patch +++ b/3.2.40/1025_linux-3.2.26.patch diff --git a/3.2.39/1026_linux-3.2.27.patch b/3.2.40/1026_linux-3.2.27.patch index 5878eb4..5878eb4 100644 --- a/3.2.39/1026_linux-3.2.27.patch +++ b/3.2.40/1026_linux-3.2.27.patch diff --git a/3.2.39/1027_linux-3.2.28.patch b/3.2.40/1027_linux-3.2.28.patch index 4dbba4b..4dbba4b 100644 --- a/3.2.39/1027_linux-3.2.28.patch +++ b/3.2.40/1027_linux-3.2.28.patch diff --git a/3.2.39/1028_linux-3.2.29.patch b/3.2.40/1028_linux-3.2.29.patch index 3c65179..3c65179 100644 --- a/3.2.39/1028_linux-3.2.29.patch +++ b/3.2.40/1028_linux-3.2.29.patch diff --git a/3.2.39/1029_linux-3.2.30.patch b/3.2.40/1029_linux-3.2.30.patch index 86aea4b..86aea4b 100644 --- a/3.2.39/1029_linux-3.2.30.patch +++ b/3.2.40/1029_linux-3.2.30.patch diff --git a/3.2.39/1030_linux-3.2.31.patch b/3.2.40/1030_linux-3.2.31.patch index c6accf5..c6accf5 100644 --- a/3.2.39/1030_linux-3.2.31.patch +++ b/3.2.40/1030_linux-3.2.31.patch diff --git a/3.2.39/1031_linux-3.2.32.patch b/3.2.40/1031_linux-3.2.32.patch index 247fc0b..247fc0b 100644 --- a/3.2.39/1031_linux-3.2.32.patch +++ b/3.2.40/1031_linux-3.2.32.patch diff --git a/3.2.39/1032_linux-3.2.33.patch b/3.2.40/1032_linux-3.2.33.patch index c32fb75..c32fb75 100644 --- a/3.2.39/1032_linux-3.2.33.patch +++ b/3.2.40/1032_linux-3.2.33.patch diff --git a/3.2.39/1033_linux-3.2.34.patch b/3.2.40/1033_linux-3.2.34.patch index d647b38..d647b38 100644 --- a/3.2.39/1033_linux-3.2.34.patch +++ b/3.2.40/1033_linux-3.2.34.patch diff --git a/3.2.39/1034_linux-3.2.35.patch b/3.2.40/1034_linux-3.2.35.patch index 76a9c19..76a9c19 100644 --- a/3.2.39/1034_linux-3.2.35.patch +++ b/3.2.40/1034_linux-3.2.35.patch diff --git a/3.2.39/1035_linux-3.2.36.patch b/3.2.40/1035_linux-3.2.36.patch index 5d192a3..5d192a3 100644 --- a/3.2.39/1035_linux-3.2.36.patch +++ b/3.2.40/1035_linux-3.2.36.patch diff --git a/3.2.39/1036_linux-3.2.37.patch b/3.2.40/1036_linux-3.2.37.patch index ad13251..ad13251 100644 --- a/3.2.39/1036_linux-3.2.37.patch +++ b/3.2.40/1036_linux-3.2.37.patch diff --git a/3.2.39/1037_linux-3.2.38.patch b/3.2.40/1037_linux-3.2.38.patch index a3c106f..a3c106f 100644 --- a/3.2.39/1037_linux-3.2.38.patch +++ b/3.2.40/1037_linux-3.2.38.patch diff --git a/3.2.39/1039_linux-3.2.39.patch b/3.2.40/1038_linux-3.2.39.patch index 5639e92..5639e92 100644 --- a/3.2.39/1039_linux-3.2.39.patch +++ b/3.2.40/1038_linux-3.2.39.patch diff --git a/3.2.40/1039_linux-3.2.40.patch b/3.2.40/1039_linux-3.2.40.patch new file mode 100644 index 0000000..f26b39c --- /dev/null +++ b/3.2.40/1039_linux-3.2.40.patch @@ -0,0 +1,6295 @@ +diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt +index 81c287f..ddbf18e 100644 +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -552,6 +552,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. + UART at the specified I/O port or MMIO address, + switching to the matching ttyS device later. The + options are the same as for ttyS, above. ++ hvc<n> Use the hypervisor console device <n>. This is for ++ both Xen and PowerPC hypervisors. + + If the device connected to the port is not a TTY but a braille + device, prepend "brl," before the device type, for instance +@@ -703,6 +705,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. + + earlyprintk= [X86,SH,BLACKFIN] + earlyprintk=vga ++ earlyprintk=xen + earlyprintk=serial[,ttySn[,baudrate]] + earlyprintk=ttySn[,baudrate] + earlyprintk=dbgp[debugController#] +@@ -720,6 +723,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. + The VGA output is eventually overwritten by the real + console. + ++ The xen output can only be used by Xen PV guests. ++ + ekgdboc= [X86,KGDB] Allow early kernel console debugging + ekgdboc=kbd + +diff --git a/Makefile b/Makefile +index 0fceb8b..47af1e9 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 2 +-SUBLEVEL = 39 ++SUBLEVEL = 40 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/arm/mach-pxa/include/mach/smemc.h b/arch/arm/mach-pxa/include/mach/smemc.h +index b7de471..b802f28 100644 +--- a/arch/arm/mach-pxa/include/mach/smemc.h ++++ b/arch/arm/mach-pxa/include/mach/smemc.h +@@ -37,6 +37,7 @@ + #define CSADRCFG1 (SMEMC_VIRT + 0x84) /* Address Configuration Register for CS1 */ + #define CSADRCFG2 (SMEMC_VIRT + 0x88) /* Address Configuration Register for CS2 */ + #define CSADRCFG3 (SMEMC_VIRT + 0x8C) /* Address Configuration Register for CS3 */ ++#define CSMSADRCFG (SMEMC_VIRT + 0xA0) /* Chip Select Configuration Register */ + + /* + * More handy macros for PCMCIA +diff --git a/arch/arm/mach-pxa/smemc.c b/arch/arm/mach-pxa/smemc.c +index 7992305..f38aa89 100644 +--- a/arch/arm/mach-pxa/smemc.c ++++ b/arch/arm/mach-pxa/smemc.c +@@ -40,6 +40,8 @@ static void pxa3xx_smemc_resume(void) + __raw_writel(csadrcfg[1], CSADRCFG1); + __raw_writel(csadrcfg[2], CSADRCFG2); + __raw_writel(csadrcfg[3], CSADRCFG3); ++ /* CSMSADRCFG wakes up in its default state (0), so we need to set it */ ++ __raw_writel(0x2, CSMSADRCFG); + } + + static struct syscore_ops smemc_syscore_ops = { +@@ -49,8 +51,19 @@ static struct syscore_ops smemc_syscore_ops = { + + static int __init smemc_init(void) + { +- if (cpu_is_pxa3xx()) ++ if (cpu_is_pxa3xx()) { ++ /* ++ * The only documentation we have on the ++ * Chip Select Configuration Register (CSMSADRCFG) is that ++ * it must be programmed to 0x2. ++ * Moreover, in the bit definitions, the second bit ++ * (CSMSADRCFG[1]) is called "SETALWAYS". ++ * Other bits are reserved in this register. ++ */ ++ __raw_writel(0x2, CSMSADRCFG); ++ + register_syscore_ops(&smemc_syscore_ops); ++ } + + return 0; + } +diff --git a/arch/arm/mach-s3c2410/include/mach/debug-macro.S b/arch/arm/mach-s3c2410/include/mach/debug-macro.S +index 4135de8..13ed33c 100644 +--- a/arch/arm/mach-s3c2410/include/mach/debug-macro.S ++++ b/arch/arm/mach-s3c2410/include/mach/debug-macro.S +@@ -40,17 +40,17 @@ + addeq \rd, \rx, #(S3C24XX_PA_GPIO - S3C24XX_PA_UART) + addne \rd, \rx, #(S3C24XX_VA_GPIO - S3C24XX_VA_UART) + bic \rd, \rd, #0xff000 +- ldr \rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ] ++ ldr \rd, [\rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0)] + and \rd, \rd, #0x00ff0000 + teq \rd, #0x00440000 @ is it 2440? + 1004: +- ldr \rd, [ \rx, # S3C2410_UFSTAT ] ++ ldr \rd, [\rx, # S3C2410_UFSTAT] + moveq \rd, \rd, lsr #SHIFT_2440TXF + tst \rd, #S3C2410_UFSTAT_TXFULL + .endm + + .macro fifo_full_s3c2410 rd, rx +- ldr \rd, [ \rx, # S3C2410_UFSTAT ] ++ ldr \rd, [\rx, # S3C2410_UFSTAT] + tst \rd, #S3C2410_UFSTAT_TXFULL + .endm + +@@ -68,18 +68,18 @@ + addeq \rd, \rx, #(S3C24XX_PA_GPIO - S3C24XX_PA_UART) + addne \rd, \rx, #(S3C24XX_VA_GPIO - S3C24XX_VA_UART) + bic \rd, \rd, #0xff000 +- ldr \rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ] ++ ldr \rd, [\rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0)] + and \rd, \rd, #0x00ff0000 + teq \rd, #0x00440000 @ is it 2440? + + 10000: +- ldr \rd, [ \rx, # S3C2410_UFSTAT ] ++ ldr \rd, [\rx, # S3C2410_UFSTAT] + andne \rd, \rd, #S3C2410_UFSTAT_TXMASK + andeq \rd, \rd, #S3C2440_UFSTAT_TXMASK + .endm + + .macro fifo_level_s3c2410 rd, rx +- ldr \rd, [ \rx, # S3C2410_UFSTAT ] ++ ldr \rd, [\rx, # S3C2410_UFSTAT] + and \rd, \rd, #S3C2410_UFSTAT_TXMASK + .endm + +diff --git a/arch/arm/mach-s3c2410/include/mach/entry-macro.S b/arch/arm/mach-s3c2410/include/mach/entry-macro.S +index 473b3cd..ef2287b 100644 +--- a/arch/arm/mach-s3c2410/include/mach/entry-macro.S ++++ b/arch/arm/mach-s3c2410/include/mach/entry-macro.S +@@ -34,10 +34,10 @@ + + @@ try the interrupt offset register, since it is there + +- ldr \irqstat, [ \base, #INTPND ] ++ ldr \irqstat, [\base, #INTPND ] + teq \irqstat, #0 + beq 1002f +- ldr \irqnr, [ \base, #INTOFFSET ] ++ ldr \irqnr, [\base, #INTOFFSET ] + mov \tmp, #1 + tst \irqstat, \tmp, lsl \irqnr + bne 1001f +diff --git a/arch/arm/mach-s3c2410/pm-h1940.S b/arch/arm/mach-s3c2410/pm-h1940.S +index c93bf2d..6183a68 100644 +--- a/arch/arm/mach-s3c2410/pm-h1940.S ++++ b/arch/arm/mach-s3c2410/pm-h1940.S +@@ -30,4 +30,4 @@ + + h1940_pm_return: + mov r0, #S3C2410_PA_GPIO +- ldr pc, [ r0, #S3C2410_GSTATUS3 - S3C24XX_VA_GPIO ] ++ ldr pc, [r0, #S3C2410_GSTATUS3 - S3C24XX_VA_GPIO] +diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S +index dd5b638..65200ae 100644 +--- a/arch/arm/mach-s3c2410/sleep.S ++++ b/arch/arm/mach-s3c2410/sleep.S +@@ -45,9 +45,9 @@ ENTRY(s3c2410_cpu_suspend) + ldr r4, =S3C2410_REFRESH + ldr r5, =S3C24XX_MISCCR + ldr r6, =S3C2410_CLKCON +- ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB) +- ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB) +- ldr r9, [ r6 ] @ get CLKCON (and ensure in TLB) ++ ldr r7, [r4] @ get REFRESH (and ensure in TLB) ++ ldr r8, [r5] @ get MISCCR (and ensure in TLB) ++ ldr r9, [r6] @ get CLKCON (and ensure in TLB) + + orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command + orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals +@@ -61,8 +61,8 @@ ENTRY(s3c2410_cpu_suspend) + @@ align next bit of code to cache line + .align 5 + s3c2410_do_sleep: +- streq r7, [ r4 ] @ SDRAM sleep command +- streq r8, [ r5 ] @ SDRAM power-down config +- streq r9, [ r6 ] @ CPU sleep ++ streq r7, [r4] @ SDRAM sleep command ++ streq r8, [r5] @ SDRAM power-down config ++ streq r9, [r6] @ CPU sleep + 1: beq 1b + mov pc, r14 +diff --git a/arch/arm/mach-s3c2412/sleep.S b/arch/arm/mach-s3c2412/sleep.S +index c82418e..5adaceb 100644 +--- a/arch/arm/mach-s3c2412/sleep.S ++++ b/arch/arm/mach-s3c2412/sleep.S +@@ -57,12 +57,12 @@ s3c2412_sleep_enter1: + * retry, as simply returning causes the system to lock. + */ + +- ldrne r9, [ r1 ] +- strne r9, [ r1 ] +- ldrne r9, [ r2 ] +- strne r9, [ r2 ] +- ldrne r9, [ r3 ] +- strne r9, [ r3 ] ++ ldrne r9, [r1] ++ strne r9, [r1] ++ ldrne r9, [r2] ++ strne r9, [r2] ++ ldrne r9, [r3] ++ strne r9, [r3] + bne s3c2412_sleep_enter1 + + mov pc, r14 +diff --git a/arch/arm/mach-w90x900/include/mach/entry-macro.S b/arch/arm/mach-w90x900/include/mach/entry-macro.S +index d39aca5..08436cf 100644 +--- a/arch/arm/mach-w90x900/include/mach/entry-macro.S ++++ b/arch/arm/mach-w90x900/include/mach/entry-macro.S +@@ -22,8 +22,8 @@ + + mov \base, #AIC_BA + +- ldr \irqnr, [ \base, #AIC_IPER] +- ldr \irqnr, [ \base, #AIC_ISNR] ++ ldr \irqnr, [\base, #AIC_IPER] ++ ldr \irqnr, [\base, #AIC_ISNR] + cmp \irqnr, #0 + + .endm +diff --git a/arch/arm/plat-samsung/include/plat/debug-macro.S b/arch/arm/plat-samsung/include/plat/debug-macro.S +index 207e275..f3a9cff 100644 +--- a/arch/arm/plat-samsung/include/plat/debug-macro.S ++++ b/arch/arm/plat-samsung/include/plat/debug-macro.S +@@ -14,12 +14,12 @@ + /* The S5PV210/S5PC110 implementations are as belows. */ + + .macro fifo_level_s5pv210 rd, rx +- ldr \rd, [ \rx, # S3C2410_UFSTAT ] ++ ldr \rd, [\rx, # S3C2410_UFSTAT] + and \rd, \rd, #S5PV210_UFSTAT_TXMASK + .endm + + .macro fifo_full_s5pv210 rd, rx +- ldr \rd, [ \rx, # S3C2410_UFSTAT ] ++ ldr \rd, [\rx, # S3C2410_UFSTAT] + tst \rd, #S5PV210_UFSTAT_TXFULL + .endm + +@@ -27,7 +27,7 @@ + * most widely re-used */ + + .macro fifo_level_s3c2440 rd, rx +- ldr \rd, [ \rx, # S3C2410_UFSTAT ] ++ ldr \rd, [\rx, # S3C2410_UFSTAT] + and \rd, \rd, #S3C2440_UFSTAT_TXMASK + .endm + +@@ -36,7 +36,7 @@ + #endif + + .macro fifo_full_s3c2440 rd, rx +- ldr \rd, [ \rx, # S3C2410_UFSTAT ] ++ ldr \rd, [\rx, # S3C2410_UFSTAT] + tst \rd, #S3C2440_UFSTAT_TXFULL + .endm + +@@ -45,11 +45,11 @@ + #endif + + .macro senduart,rd,rx +- strb \rd, [\rx, # S3C2410_UTXH ] ++ strb \rd, [\rx, # S3C2410_UTXH] + .endm + + .macro busyuart, rd, rx +- ldr \rd, [ \rx, # S3C2410_UFCON ] ++ ldr \rd, [\rx, # S3C2410_UFCON] + tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled? + beq 1001f @ + @ FIFO enabled... +@@ -60,7 +60,7 @@ + + 1001: + @ busy waiting for non fifo +- ldr \rd, [ \rx, # S3C2410_UTRSTAT ] ++ ldr \rd, [\rx, # S3C2410_UTRSTAT] + tst \rd, #S3C2410_UTRSTAT_TXFE + beq 1001b + +@@ -68,7 +68,7 @@ + .endm + + .macro waituart,rd,rx +- ldr \rd, [ \rx, # S3C2410_UFCON ] ++ ldr \rd, [\rx, # S3C2410_UFCON] + tst \rd, #S3C2410_UFCON_FIFOMODE @ fifo enabled? + beq 1001f @ + @ FIFO enabled... +@@ -79,7 +79,7 @@ + b 1002f + 1001: + @ idle waiting for non fifo +- ldr \rd, [ \rx, # S3C2410_UTRSTAT ] ++ ldr \rd, [\rx, # S3C2410_UTRSTAT] + tst \rd, #S3C2410_UTRSTAT_TXFE + beq 1001b + +diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h +index 22dadeb..9d35a3e 100644 +--- a/arch/parisc/include/asm/pgtable.h ++++ b/arch/parisc/include/asm/pgtable.h +@@ -12,11 +12,10 @@ + + #include <linux/bitops.h> + #include <linux/spinlock.h> ++#include <linux/mm_types.h> + #include <asm/processor.h> + #include <asm/cache.h> + +-struct vm_area_struct; +- + /* + * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel + * memory. For the return value to be meaningful, ADDR must be >= +@@ -40,7 +39,14 @@ struct vm_area_struct; + do{ \ + *(pteptr) = (pteval); \ + } while(0) +-#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) ++ ++extern void purge_tlb_entries(struct mm_struct *, unsigned long); ++ ++#define set_pte_at(mm, addr, ptep, pteval) \ ++ do { \ ++ set_pte(ptep, pteval); \ ++ purge_tlb_entries(mm, addr); \ ++ } while (0) + + #endif /* !__ASSEMBLY__ */ + +@@ -464,6 +470,7 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, + old = pte_val(*ptep); + new = pte_val(pte_wrprotect(__pte (old))); + } while (cmpxchg((unsigned long *) ptep, old, new) != old); ++ purge_tlb_entries(mm, addr); + #else + pte_t old_pte = *ptep; + set_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); +diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c +index 83335f3..5241698 100644 +--- a/arch/parisc/kernel/cache.c ++++ b/arch/parisc/kernel/cache.c +@@ -421,6 +421,24 @@ void kunmap_parisc(void *addr) + EXPORT_SYMBOL(kunmap_parisc); + #endif + ++void purge_tlb_entries(struct mm_struct *mm, unsigned long addr) ++{ ++ unsigned long flags; ++ ++ /* Note: purge_tlb_entries can be called at startup with ++ no context. */ ++ ++ /* Disable preemption while we play with %sr1. */ ++ preempt_disable(); ++ mtsp(mm->context, 1); ++ purge_tlb_start(flags); ++ pdtlb(addr); ++ pitlb(addr); ++ purge_tlb_end(flags); ++ preempt_enable(); ++} ++EXPORT_SYMBOL(purge_tlb_entries); ++ + void __flush_tlb_range(unsigned long sid, unsigned long start, + unsigned long end) + { +diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h +index 66ea9b8..21165a4 100644 +--- a/arch/powerpc/include/asm/eeh.h ++++ b/arch/powerpc/include/asm/eeh.h +@@ -61,6 +61,7 @@ void __init pci_addr_cache_build(void); + */ + void eeh_add_device_tree_early(struct device_node *); + void eeh_add_device_tree_late(struct pci_bus *); ++void eeh_add_sysfs_files(struct pci_bus *); + + /** + * eeh_remove_device_recursive - undo EEH for device & children. +@@ -105,6 +106,8 @@ static inline void eeh_add_device_tree_early(struct device_node *dn) { } + + static inline void eeh_add_device_tree_late(struct pci_bus *bus) { } + ++static inline void eeh_add_sysfs_files(struct pci_bus *bus) { } ++ + static inline void eeh_remove_bus_device(struct pci_dev *dev) { } + #define EEH_POSSIBLE_ERROR(val, type) (0) + #define EEH_IO_ERROR_VALUE(size) (-1UL) +diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c +index 26ccbf7..4c0908d 100644 +--- a/arch/powerpc/kernel/machine_kexec_64.c ++++ b/arch/powerpc/kernel/machine_kexec_64.c +@@ -162,6 +162,8 @@ static int kexec_all_irq_disabled = 0; + static void kexec_smp_down(void *arg) + { + local_irq_disable(); ++ hard_irq_disable(); ++ + mb(); /* make sure our irqs are disabled before we say they are */ + get_paca()->kexec_state = KEXEC_STATE_IRQS_OFF; + while(kexec_all_irq_disabled == 0) +@@ -244,6 +246,8 @@ static void kexec_prepare_cpus(void) + wake_offline_cpus(); + smp_call_function(kexec_smp_down, NULL, /* wait */0); + local_irq_disable(); ++ hard_irq_disable(); ++ + mb(); /* make sure IRQs are disabled before we say they are */ + get_paca()->kexec_state = KEXEC_STATE_IRQS_OFF; + +@@ -281,6 +285,7 @@ static void kexec_prepare_cpus(void) + if (ppc_md.kexec_cpu_down) + ppc_md.kexec_cpu_down(0, 0); + local_irq_disable(); ++ hard_irq_disable(); + } + + #endif /* SMP */ +diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c +index e1612df..b10beef 100644 +--- a/arch/powerpc/kernel/of_platform.c ++++ b/arch/powerpc/kernel/of_platform.c +@@ -91,6 +91,9 @@ static int __devinit of_pci_phb_probe(struct platform_device *dev) + /* Add probed PCI devices to the device model */ + pci_bus_add_devices(phb->bus); + ++ /* sysfs files should only be added after devices are added */ ++ eeh_add_sysfs_files(phb->bus); ++ + return 0; + } + +diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c +index 458ed3b..a3cd949 100644 +--- a/arch/powerpc/kernel/pci-common.c ++++ b/arch/powerpc/kernel/pci-common.c +@@ -1536,11 +1536,14 @@ void pcibios_finish_adding_to_bus(struct pci_bus *bus) + pcibios_allocate_bus_resources(bus); + pcibios_claim_one_bus(bus); + ++ /* Fixup EEH */ ++ eeh_add_device_tree_late(bus); ++ + /* Add new devices to global lists. Register in proc, sysfs. */ + pci_bus_add_devices(bus); + +- /* Fixup EEH */ +- eeh_add_device_tree_late(bus); ++ /* sysfs files should only be added after devices are added */ ++ eeh_add_sysfs_files(bus); + } + EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus); + +diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c +index 5658690..389e06b 100644 +--- a/arch/powerpc/platforms/pseries/eeh.c ++++ b/arch/powerpc/platforms/pseries/eeh.c +@@ -1238,7 +1238,6 @@ static void eeh_add_device_late(struct pci_dev *dev) + pdn->pcidev = dev; + + pci_addr_cache_insert_device(dev); +- eeh_sysfs_add_device(dev); + } + + void eeh_add_device_tree_late(struct pci_bus *bus) +@@ -1257,6 +1256,29 @@ void eeh_add_device_tree_late(struct pci_bus *bus) + EXPORT_SYMBOL_GPL(eeh_add_device_tree_late); + + /** ++ * eeh_add_sysfs_files - Add EEH sysfs files for the indicated PCI bus ++ * @bus: PCI bus ++ * ++ * This routine must be used to add EEH sysfs files for PCI ++ * devices which are attached to the indicated PCI bus. The PCI bus ++ * is added after system boot through hotplug or dlpar. ++ */ ++void eeh_add_sysfs_files(struct pci_bus *bus) ++{ ++ struct pci_dev *dev; ++ ++ list_for_each_entry(dev, &bus->devices, bus_list) { ++ eeh_sysfs_add_device(dev); ++ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { ++ struct pci_bus *subbus = dev->subordinate; ++ if (subbus) ++ eeh_add_sysfs_files(subbus); ++ } ++ } ++} ++EXPORT_SYMBOL_GPL(eeh_add_sysfs_files); ++ ++/** + * eeh_remove_device - undo EEH setup for the indicated pci device + * @dev: pci device to be removed + * +diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c +index 8644366..b2f44de 100644 +--- a/arch/s390/kernel/time.c ++++ b/arch/s390/kernel/time.c +@@ -121,6 +121,9 @@ static int s390_next_ktime(ktime_t expires, + nsecs = ktime_to_ns(ktime_add(timespec_to_ktime(ts), expires)); + do_div(nsecs, 125); + S390_lowcore.clock_comparator = sched_clock_base_cc + (nsecs << 9); ++ /* Program the maximum value if we have an overflow (== year 2042) */ ++ if (unlikely(S390_lowcore.clock_comparator < sched_clock_base_cc)) ++ S390_lowcore.clock_comparator = -1ULL; + set_clock_comparator(S390_lowcore.clock_comparator); + return 0; + } +diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c +index dffcaa4..4db9b1e 100644 +--- a/arch/s390/kvm/kvm-s390.c ++++ b/arch/s390/kvm/kvm-s390.c +@@ -597,6 +597,14 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr) + } else + prefix = 0; + ++ /* ++ * The guest FPRS and ACRS are in the host FPRS/ACRS due to the lazy ++ * copying in vcpu load/put. Lets update our copies before we save ++ * it into the save area ++ */ ++ save_fp_regs(&vcpu->arch.guest_fpregs); ++ save_access_regs(vcpu->arch.guest_acrs); ++ + if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs), + vcpu->arch.guest_fpregs.fprs, 128, prefix)) + return -EFAULT; +diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig +index efb4294..9a42703 100644 +--- a/arch/x86/Kconfig ++++ b/arch/x86/Kconfig +@@ -1150,7 +1150,7 @@ config DIRECT_GBPAGES + config NUMA + bool "Numa Memory Allocation and Scheduler Support" + depends on SMP +- depends on X86_64 || (X86_32 && HIGHMEM64G && (X86_NUMAQ || X86_BIGSMP || X86_SUMMIT && ACPI) && EXPERIMENTAL) ++ depends on X86_64 || (X86_32 && HIGHMEM64G && (X86_NUMAQ || X86_BIGSMP || X86_SUMMIT && ACPI) && BROKEN) + default y if (X86_NUMAQ || X86_SUMMIT || X86_BIGSMP) + ---help--- + Enable NUMA (Non Uniform Memory Access) support. +diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h +index 884507e..6be9909 100644 +--- a/arch/x86/include/asm/pgtable.h ++++ b/arch/x86/include/asm/pgtable.h +@@ -142,6 +142,11 @@ static inline unsigned long pmd_pfn(pmd_t pmd) + return (pmd_val(pmd) & PTE_PFN_MASK) >> PAGE_SHIFT; + } + ++static inline unsigned long pud_pfn(pud_t pud) ++{ ++ return (pud_val(pud) & PTE_PFN_MASK) >> PAGE_SHIFT; ++} ++ + #define pte_page(pte) pfn_to_page(pte_pfn(pte)) + + static inline int pmd_large(pmd_t pte) +diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c +index f5373df..db4f704 100644 +--- a/arch/x86/kernel/apic/x2apic_phys.c ++++ b/arch/x86/kernel/apic/x2apic_phys.c +@@ -20,12 +20,19 @@ static int set_x2apic_phys_mode(char *arg) + } + early_param("x2apic_phys", set_x2apic_phys_mode); + ++static bool x2apic_fadt_phys(void) ++{ ++ if ((acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) && ++ (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) { ++ printk(KERN_DEBUG "System requires x2apic physical mode\n"); ++ return true; ++ } ++ return false; ++} ++ + static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) + { +- if (x2apic_phys) +- return x2apic_enabled(); +- else +- return 0; ++ return x2apic_enabled() && (x2apic_phys || x2apic_fadt_phys()); + } + + static void +@@ -108,7 +115,7 @@ static void init_x2apic_ldr(void) + + static int x2apic_phys_probe(void) + { +- if (x2apic_mode && x2apic_phys) ++ if (x2apic_mode && (x2apic_phys || x2apic_fadt_phys())) + return 1; + + return apic == &apic_x2apic_phys; +diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c +index 0a630dd..646d192 100644 +--- a/arch/x86/kernel/cpu/mshyperv.c ++++ b/arch/x86/kernel/cpu/mshyperv.c +@@ -68,7 +68,8 @@ static void __init ms_hyperv_init_platform(void) + printk(KERN_INFO "HyperV: features 0x%x, hints 0x%x\n", + ms_hyperv.features, ms_hyperv.hints); + +- clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100); ++ if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE) ++ clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100); + } + + const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { +diff --git a/arch/x86/kernel/head.c b/arch/x86/kernel/head.c +index af0699b..f6c4674 100644 +--- a/arch/x86/kernel/head.c ++++ b/arch/x86/kernel/head.c +@@ -5,8 +5,6 @@ + #include <asm/setup.h> + #include <asm/bios_ebda.h> + +-#define BIOS_LOWMEM_KILOBYTES 0x413 +- + /* + * The BIOS places the EBDA/XBDA at the top of conventional + * memory, and usually decreases the reported amount of +@@ -16,17 +14,30 @@ + * chipset: reserve a page before VGA to prevent PCI prefetch + * into it (errata #56). Usually the page is reserved anyways, + * unless you have no PS/2 mouse plugged in. ++ * ++ * This functions is deliberately very conservative. Losing ++ * memory in the bottom megabyte is rarely a problem, as long ++ * as we have enough memory to install the trampoline. Using ++ * memory that is in use by the BIOS or by some DMA device ++ * the BIOS didn't shut down *is* a big problem. + */ ++ ++#define BIOS_LOWMEM_KILOBYTES 0x413 ++#define LOWMEM_CAP 0x9f000U /* Absolute maximum */ ++#define INSANE_CUTOFF 0x20000U /* Less than this = insane */ ++ + void __init reserve_ebda_region(void) + { + unsigned int lowmem, ebda_addr; + +- /* To determine the position of the EBDA and the */ +- /* end of conventional memory, we need to look at */ +- /* the BIOS data area. In a paravirtual environment */ +- /* that area is absent. We'll just have to assume */ +- /* that the paravirt case can handle memory setup */ +- /* correctly, without our help. */ ++ /* ++ * To determine the position of the EBDA and the ++ * end of conventional memory, we need to look at ++ * the BIOS data area. In a paravirtual environment ++ * that area is absent. We'll just have to assume ++ * that the paravirt case can handle memory setup ++ * correctly, without our help. ++ */ + if (paravirt_enabled()) + return; + +@@ -37,19 +48,23 @@ void __init reserve_ebda_region(void) + /* start of EBDA area */ + ebda_addr = get_bios_ebda(); + +- /* Fixup: bios puts an EBDA in the top 64K segment */ +- /* of conventional memory, but does not adjust lowmem. */ +- if ((lowmem - ebda_addr) <= 0x10000) +- lowmem = ebda_addr; ++ /* ++ * Note: some old Dells seem to need 4k EBDA without ++ * reporting so, so just consider the memory above 0x9f000 ++ * to be off limits (bugzilla 2990). ++ */ ++ ++ /* If the EBDA address is below 128K, assume it is bogus */ ++ if (ebda_addr < INSANE_CUTOFF) ++ ebda_addr = LOWMEM_CAP; + +- /* Fixup: bios does not report an EBDA at all. */ +- /* Some old Dells seem to need 4k anyhow (bugzilla 2990) */ +- if ((ebda_addr == 0) && (lowmem >= 0x9f000)) +- lowmem = 0x9f000; ++ /* If lowmem is less than 128K, assume it is bogus */ ++ if (lowmem < INSANE_CUTOFF) ++ lowmem = LOWMEM_CAP; + +- /* Paranoia: should never happen, but... */ +- if ((lowmem == 0) || (lowmem >= 0x100000)) +- lowmem = 0x9f000; ++ /* Use the lower of the lowmem and EBDA markers as the cutoff */ ++ lowmem = min(lowmem, ebda_addr); ++ lowmem = min(lowmem, LOWMEM_CAP); /* Absolute cap */ + + /* reserve all memory between lowmem and the 1MB mark */ + memblock_x86_reserve_range(lowmem, 0x100000, "* BIOS reserved"); +diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c +index 5db0490..7b73c88 100644 +--- a/arch/x86/mm/fault.c ++++ b/arch/x86/mm/fault.c +@@ -738,13 +738,15 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, + return; + } + #endif ++ /* Kernel addresses are always protection faults: */ ++ if (address >= TASK_SIZE) ++ error_code |= PF_PROT; + +- if (unlikely(show_unhandled_signals)) ++ if (likely(show_unhandled_signals)) + show_signal_msg(regs, error_code, address, tsk); + +- /* Kernel addresses are always protection faults: */ + tsk->thread.cr2 = address; +- tsk->thread.error_code = error_code | (address >= TASK_SIZE); ++ tsk->thread.error_code = error_code; + tsk->thread.trap_no = 14; + + force_sig_info_fault(SIGSEGV, si_code, address, tsk, 0); +diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c +index bbaaa00..44b93da 100644 +--- a/arch/x86/mm/init_64.c ++++ b/arch/x86/mm/init_64.c +@@ -831,6 +831,9 @@ int kern_addr_valid(unsigned long addr) + if (pud_none(*pud)) + return 0; + ++ if (pud_large(*pud)) ++ return pfn_valid(pud_pfn(*pud)); ++ + pmd = pmd_offset(pud, addr); + if (pmd_none(*pmd)) + return 0; +diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c +index bef9991..1de542b 100644 +--- a/arch/x86/platform/efi/efi.c ++++ b/arch/x86/platform/efi/efi.c +@@ -83,9 +83,10 @@ int efi_enabled(int facility) + } + EXPORT_SYMBOL(efi_enabled); + ++static bool disable_runtime = false; + static int __init setup_noefi(char *arg) + { +- clear_bit(EFI_BOOT, &x86_efi_facility); ++ disable_runtime = true; + return 0; + } + early_param("noefi", setup_noefi); +@@ -549,35 +550,37 @@ void __init efi_init(void) + + set_bit(EFI_CONFIG_TABLES, &x86_efi_facility); + +- /* +- * Check out the runtime services table. We need to map +- * the runtime services table so that we can grab the physical +- * address of several of the EFI runtime functions, needed to +- * set the firmware into virtual mode. +- */ +- runtime = early_ioremap((unsigned long)efi.systab->runtime, +- sizeof(efi_runtime_services_t)); +- if (runtime != NULL) { +- /* +- * We will only need *early* access to the following +- * two EFI runtime services before set_virtual_address_map +- * is invoked. +- */ +- efi_phys.get_time = (efi_get_time_t *)runtime->get_time; +- efi_phys.set_virtual_address_map = +- (efi_set_virtual_address_map_t *) +- runtime->set_virtual_address_map; ++ if (!disable_runtime) { + /* +- * Make efi_get_time can be called before entering +- * virtual mode. ++ * Check out the runtime services table. We need to map ++ * the runtime services table so that we can grab the physical ++ * address of several of the EFI runtime functions, needed to ++ * set the firmware into virtual mode. + */ +- efi.get_time = phys_efi_get_time; +- +- set_bit(EFI_RUNTIME_SERVICES, &x86_efi_facility); +- } else +- printk(KERN_ERR "Could not map the EFI runtime service " +- "table!\n"); +- early_iounmap(runtime, sizeof(efi_runtime_services_t)); ++ runtime = early_ioremap((unsigned long)efi.systab->runtime, ++ sizeof(efi_runtime_services_t)); ++ if (runtime != NULL) { ++ /* ++ * We will only need *early* access to the following ++ * two EFI runtime services before set_virtual_address_map ++ * is invoked. ++ */ ++ efi_phys.get_time = (efi_get_time_t *)runtime->get_time; ++ efi_phys.set_virtual_address_map = ++ (efi_set_virtual_address_map_t *) ++ runtime->set_virtual_address_map; ++ /* ++ * Make efi_get_time can be called before entering ++ * virtual mode. ++ */ ++ efi.get_time = phys_efi_get_time; ++ ++ set_bit(EFI_RUNTIME_SERVICES, &x86_efi_facility); ++ } else ++ printk(KERN_ERR "Could not map the EFI runtime service " ++ "table!\n"); ++ early_iounmap(runtime, sizeof(efi_runtime_services_t)); ++ } + + /* Map the EFI memory map */ + memmap.map = early_ioremap((unsigned long)memmap.phys_map, +diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c +index d69cc6c..67bc7ba 100644 +--- a/arch/x86/xen/spinlock.c ++++ b/arch/x86/xen/spinlock.c +@@ -328,7 +328,6 @@ static noinline void xen_spin_unlock_slow(struct xen_spinlock *xl) + if (per_cpu(lock_spinners, cpu) == xl) { + ADD_STATS(released_slow_kicked, 1); + xen_send_IPI_one(cpu, XEN_SPIN_UNLOCK_VECTOR); +- break; + } + } + } +diff --git a/block/genhd.c b/block/genhd.c +index 4927476..6edf228 100644 +--- a/block/genhd.c ++++ b/block/genhd.c +@@ -26,7 +26,7 @@ static DEFINE_MUTEX(block_class_lock); + struct kobject *block_depr; + + /* for extended dynamic devt allocation, currently only one major is used */ +-#define MAX_EXT_DEVT (1 << MINORBITS) ++#define NR_EXT_DEVT (1 << MINORBITS) + + /* For extended devt allocation. ext_devt_mutex prevents look up + * results from going away underneath its user. +@@ -421,17 +421,18 @@ int blk_alloc_devt(struct hd_struct *part, dev_t *devt) + do { + if (!idr_pre_get(&ext_devt_idr, GFP_KERNEL)) + return -ENOMEM; ++ mutex_lock(&ext_devt_mutex); + rc = idr_get_new(&ext_devt_idr, part, &idx); ++ if (!rc && idx >= NR_EXT_DEVT) { ++ idr_remove(&ext_devt_idr, idx); ++ rc = -EBUSY; ++ } ++ mutex_unlock(&ext_devt_mutex); + } while (rc == -EAGAIN); + + if (rc) + return rc; + +- if (idx > MAX_EXT_DEVT) { +- idr_remove(&ext_devt_idr, idx); +- return -EBUSY; +- } +- + *devt = MKDEV(BLOCK_EXT_MAJOR, blk_mangle_minor(idx)); + return 0; + } +@@ -645,7 +646,6 @@ void del_gendisk(struct gendisk *disk) + disk_part_iter_exit(&piter); + + invalidate_partition(disk, 0); +- blk_free_devt(disk_to_dev(disk)->devt); + set_capacity(disk, 0); + disk->flags &= ~GENHD_FL_UP; + +@@ -663,6 +663,7 @@ void del_gendisk(struct gendisk *disk) + if (!sysfs_deprecated) + sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk))); + device_del(disk_to_dev(disk)); ++ blk_free_devt(disk_to_dev(disk)->devt); + } + EXPORT_SYMBOL(del_gendisk); + +diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c +index d790791..cc9d020 100644 +--- a/drivers/acpi/sleep.c ++++ b/drivers/acpi/sleep.c +@@ -156,6 +156,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { + }, + { + .callback = init_nvs_nosave, ++ .ident = "Sony Vaio VGN-FW41E_H", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW41E_H"), ++ }, ++ }, ++ { ++ .callback = init_nvs_nosave, + .ident = "Sony Vaio VGN-FW21E", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), +diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c +index 69ac373..df47397 100644 +--- a/drivers/ata/ata_piix.c ++++ b/drivers/ata/ata_piix.c +@@ -321,6 +321,41 @@ static const struct pci_device_id piix_pci_tbl[] = { + { 0x8086, 0x1e08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, + /* SATA Controller IDE (Panther Point) */ + { 0x8086, 0x1e09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, ++ /* SATA Controller IDE (Lynx Point) */ ++ { 0x8086, 0x8c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, ++ /* SATA Controller IDE (Lynx Point) */ ++ { 0x8086, 0x8c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, ++ /* SATA Controller IDE (Lynx Point) */ ++ { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, ++ /* SATA Controller IDE (Lynx Point) */ ++ { 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, ++ /* SATA Controller IDE (Lynx Point-LP) */ ++ { 0x8086, 0x9c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, ++ /* SATA Controller IDE (Lynx Point-LP) */ ++ { 0x8086, 0x9c01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, ++ /* SATA Controller IDE (Lynx Point-LP) */ ++ { 0x8086, 0x9c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, ++ /* SATA Controller IDE (Lynx Point-LP) */ ++ { 0x8086, 0x9c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, ++ /* SATA Controller IDE (DH89xxCC) */ ++ { 0x8086, 0x2326, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, ++ /* SATA Controller IDE (Avoton) */ ++ { 0x8086, 0x1f20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, ++ /* SATA Controller IDE (Avoton) */ ++ { 0x8086, 0x1f21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, ++ /* SATA Controller IDE (Avoton) */ ++ { 0x8086, 0x1f30, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, ++ /* SATA Controller IDE (Avoton) */ ++ { 0x8086, 0x1f31, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, ++ /* SATA Controller IDE (Wellsburg) */ ++ { 0x8086, 0x8d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, ++ /* SATA Controller IDE (Wellsburg) */ ++ { 0x8086, 0x8d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, ++ /* SATA Controller IDE (Wellsburg) */ ++ { 0x8086, 0x8d60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb }, ++ /* SATA Controller IDE (Wellsburg) */ ++ { 0x8086, 0x8d68, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, ++ + { } /* terminate list */ + }; + +diff --git a/drivers/base/bus.c b/drivers/base/bus.c +index 000e7b2..8b8e8c0 100644 +--- a/drivers/base/bus.c ++++ b/drivers/base/bus.c +@@ -289,7 +289,7 @@ int bus_for_each_dev(struct bus_type *bus, struct device *start, + struct device *dev; + int error = 0; + +- if (!bus) ++ if (!bus || !bus->p) + return -EINVAL; + + klist_iter_init_node(&bus->p->klist_devices, &i, +@@ -323,7 +323,7 @@ struct device *bus_find_device(struct bus_type *bus, + struct klist_iter i; + struct device *dev; + +- if (!bus) ++ if (!bus || !bus->p) + return NULL; + + klist_iter_init_node(&bus->p->klist_devices, &i, +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 86848c6..40a0fcb 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -584,12 +584,20 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo, + struct request sreq; + + dev_info(disk_to_dev(lo->disk), "NBD_DISCONNECT\n"); ++ if (!lo->sock) ++ return -EINVAL; + ++ mutex_unlock(&lo->tx_lock); ++ fsync_bdev(bdev); ++ mutex_lock(&lo->tx_lock); + blk_rq_init(NULL, &sreq); + sreq.cmd_type = REQ_TYPE_SPECIAL; + nbd_cmd(&sreq) = NBD_CMD_DISC; ++ ++ /* Check again after getting mutex back. */ + if (!lo->sock) + return -EINVAL; ++ + nbd_send_req(lo, &sreq); + return 0; + } +@@ -603,6 +611,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo, + nbd_clear_que(lo); + BUG_ON(!list_empty(&lo->queue_head)); + BUG_ON(!list_empty(&lo->waiting_queue)); ++ kill_bdev(bdev); + if (file) + fput(file); + return 0; +@@ -683,6 +692,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo, + lo->file = NULL; + nbd_clear_que(lo); + dev_warn(disk_to_dev(lo->disk), "queue cleared\n"); ++ kill_bdev(bdev); + if (file) + fput(file); + lo->bytesize = 0; +diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c +index 48e8fee..94f6ae2 100644 +--- a/drivers/block/sunvdc.c ++++ b/drivers/block/sunvdc.c +@@ -461,7 +461,7 @@ static int generic_request(struct vdc_port *port, u8 op, void *buf, int len) + int op_len, err; + void *req_buf; + +- if (!(((u64)1 << ((u64)op - 1)) & port->operations)) ++ if (!(((u64)1 << (u64)op) & port->operations)) + return -EOPNOTSUPP; + + switch (op) { +diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c +index f759ad4..674e3c2 100644 +--- a/drivers/block/xen-blkback/xenbus.c ++++ b/drivers/block/xen-blkback/xenbus.c +@@ -364,6 +364,7 @@ static int xen_blkbk_remove(struct xenbus_device *dev) + be->blkif = NULL; + } + ++ kfree(be->mode); + kfree(be); + dev_set_drvdata(&dev->dev, NULL); + return 0; +@@ -513,6 +514,7 @@ static void backend_changed(struct xenbus_watch *watch, + = container_of(watch, struct backend_info, backend_watch); + struct xenbus_device *dev = be->dev; + int cdrom = 0; ++ unsigned long handle; + char *device_type; + + DPRINTK(""); +@@ -532,10 +534,10 @@ static void backend_changed(struct xenbus_watch *watch, + return; + } + +- if ((be->major || be->minor) && +- ((be->major != major) || (be->minor != minor))) { +- pr_warn(DRV_PFX "changing physical device (from %x:%x to %x:%x) not supported.\n", +- be->major, be->minor, major, minor); ++ if (be->major | be->minor) { ++ if (be->major != major || be->minor != minor) ++ pr_warn(DRV_PFX "changing physical device (from %x:%x to %x:%x) not supported.\n", ++ be->major, be->minor, major, minor); + return; + } + +@@ -553,36 +555,33 @@ static void backend_changed(struct xenbus_watch *watch, + kfree(device_type); + } + +- if (be->major == 0 && be->minor == 0) { +- /* Front end dir is a number, which is used as the handle. */ +- +- char *p = strrchr(dev->otherend, '/') + 1; +- long handle; +- err = strict_strtoul(p, 0, &handle); +- if (err) +- return; ++ /* Front end dir is a number, which is used as the handle. */ ++ err = strict_strtoul(strrchr(dev->otherend, '/') + 1, 0, &handle); ++ if (err) ++ return; + +- be->major = major; +- be->minor = minor; ++ be->major = major; ++ be->minor = minor; + +- err = xen_vbd_create(be->blkif, handle, major, minor, +- (NULL == strchr(be->mode, 'w')), cdrom); +- if (err) { +- be->major = 0; +- be->minor = 0; +- xenbus_dev_fatal(dev, err, "creating vbd structure"); +- return; +- } ++ err = xen_vbd_create(be->blkif, handle, major, minor, ++ !strchr(be->mode, 'w'), cdrom); + ++ if (err) ++ xenbus_dev_fatal(dev, err, "creating vbd structure"); ++ else { + err = xenvbd_sysfs_addif(dev); + if (err) { + xen_vbd_free(&be->blkif->vbd); +- be->major = 0; +- be->minor = 0; + xenbus_dev_fatal(dev, err, "creating sysfs entries"); +- return; + } ++ } + ++ if (err) { ++ kfree(be->mode); ++ be->mode = NULL; ++ be->major = 0; ++ be->minor = 0; ++ } else { + /* We're potentially connected now */ + xen_update_blkif_status(be->blkif); + } +diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c +index bc6f5fa..819dfda 100644 +--- a/drivers/dca/dca-core.c ++++ b/drivers/dca/dca-core.c +@@ -420,6 +420,11 @@ void unregister_dca_provider(struct dca_provider *dca, struct device *dev) + + raw_spin_lock_irqsave(&dca_lock, flags); + ++ if (list_empty(&dca_domains)) { ++ raw_spin_unlock_irqrestore(&dca_lock, flags); ++ return; ++ } ++ + list_del(&dca->node); + + pci_rc = dca_pci_rc_from_dev(dev); +diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c +index f3b890d..1f3dd51 100644 +--- a/drivers/firewire/core-device.c ++++ b/drivers/firewire/core-device.c +@@ -995,6 +995,10 @@ static void fw_device_init(struct work_struct *work) + ret = idr_pre_get(&fw_device_idr, GFP_KERNEL) ? + idr_get_new(&fw_device_idr, device, &minor) : + -ENOMEM; ++ if (minor >= 1 << MINORBITS) { ++ idr_remove(&fw_device_idr, minor); ++ minor = -ENOSPC; ++ } + up_write(&fw_device_rwsem); + + if (ret < 0) +diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c +index bb95d59..9080eb7 100644 +--- a/drivers/gpu/drm/drm_edid.c ++++ b/drivers/gpu/drm/drm_edid.c +@@ -87,9 +87,6 @@ static struct edid_quirk { + int product_id; + u32 quirks; + } edid_quirk_list[] = { +- /* ASUS VW222S */ +- { "ACI", 0x22a2, EDID_QUIRK_FORCE_REDUCED_BLANKING }, +- + /* Acer AL1706 */ + { "ACR", 44358, EDID_QUIRK_PREFER_LARGE_60 }, + /* Acer F51 */ +@@ -1743,7 +1740,8 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) + num_modes += add_cvt_modes(connector, edid); + num_modes += add_standard_modes(connector, edid); + num_modes += add_established_modes(connector, edid); +- num_modes += add_inferred_modes(connector, edid); ++ if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF) ++ num_modes += add_inferred_modes(connector, edid); + + if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) + edid_fixup_preferred(connector, quirks); +diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c +index 445003f..471f453 100644 +--- a/drivers/gpu/drm/drm_usb.c ++++ b/drivers/gpu/drm/drm_usb.c +@@ -19,7 +19,7 @@ int drm_get_usb_dev(struct usb_interface *interface, + + usbdev = interface_to_usbdev(interface); + dev->usbdev = usbdev; +- dev->dev = &usbdev->dev; ++ dev->dev = &interface->dev; + + mutex_lock(&drm_global_mutex); + +diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c +index 10fe480..5620192 100644 +--- a/drivers/gpu/drm/i915/i915_debugfs.c ++++ b/drivers/gpu/drm/i915/i915_debugfs.c +@@ -756,7 +756,7 @@ static int i915_error_state(struct seq_file *m, void *unused) + + seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, + error->time.tv_usec); +- seq_printf(m, "Kernel: " UTS_RELEASE); ++ seq_printf(m, "Kernel: " UTS_RELEASE "\n"); + seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); + seq_printf(m, "EIR: 0x%08x\n", error->eir); + seq_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); +diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c +index 7817429..2303c2b 100644 +--- a/drivers/gpu/drm/i915/intel_display.c ++++ b/drivers/gpu/drm/i915/intel_display.c +@@ -138,8 +138,8 @@ static const intel_limit_t intel_limits_i9xx_sdvo = { + .vco = { .min = 1400000, .max = 2800000 }, + .n = { .min = 1, .max = 6 }, + .m = { .min = 70, .max = 120 }, +- .m1 = { .min = 10, .max = 22 }, +- .m2 = { .min = 5, .max = 9 }, ++ .m1 = { .min = 8, .max = 18 }, ++ .m2 = { .min = 3, .max = 7 }, + .p = { .min = 5, .max = 80 }, + .p1 = { .min = 1, .max = 8 }, + .p2 = { .dot_limit = 200000, +@@ -3242,6 +3242,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + int plane = intel_crtc->plane; ++ u32 pctl; + + if (!intel_crtc->active) + return; +@@ -3257,6 +3258,13 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) + + intel_disable_plane(dev_priv, plane, pipe); + intel_disable_pipe(dev_priv, pipe); ++ ++ /* Disable pannel fitter if it is on this pipe. */ ++ pctl = I915_READ(PFIT_CONTROL); ++ if ((pctl & PFIT_ENABLE) && ++ ((pctl & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT) == pipe) ++ I915_WRITE(PFIT_CONTROL, 0); ++ + intel_disable_pll(dev_priv, pipe); + + intel_crtc->active = false; +diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c +index 0977849..60d13fe 100644 +--- a/drivers/gpu/drm/radeon/evergreen.c ++++ b/drivers/gpu/drm/radeon/evergreen.c +@@ -1137,6 +1137,8 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav + blackout &= ~BLACKOUT_MODE_MASK; + WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1); + } ++ /* wait for the MC to settle */ ++ udelay(100); + } + + void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) +diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c +index 279b863d..a23b63a 100644 +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1900,6 +1900,7 @@ static const struct hid_device_id hid_ignore_list[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HYBRID) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HEATCONTROL) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_BEATPAD) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_MASTERKIT, USB_DEVICE_ID_MASTERKIT_MA901RADIO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) }, +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h +index c15c38e..25f3290 100644 +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -506,6 +506,9 @@ + #define USB_VENDOR_ID_MADCATZ 0x0738 + #define USB_DEVICE_ID_MADCATZ_BEATPAD 0x4540 + ++#define USB_VENDOR_ID_MASTERKIT 0x16c0 ++#define USB_DEVICE_ID_MASTERKIT_MA901RADIO 0x05df ++ + #define USB_VENDOR_ID_MCC 0x09db + #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 + #define USB_DEVICE_ID_MCC_PMD1208LS 0x007a +diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c +index dffdca8..f44a067 100644 +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -4140,13 +4140,19 @@ static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) + { + /* + * Mobile 4 Series Chipset neglects to set RWBF capability, +- * but needs it: ++ * but needs it. Same seems to hold for the desktop versions. + */ + printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n"); + rwbf_quirk = 1; + } + + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_rwbf); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_rwbf); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_rwbf); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_rwbf); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_rwbf); ++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_rwbf); + + #define GGC 0x52 + #define GGC_MEMORY_SIZE_MASK (0xf << 8) +diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c +index 29f9000..a47ba33 100644 +--- a/drivers/media/rc/rc-main.c ++++ b/drivers/media/rc/rc-main.c +@@ -774,9 +774,12 @@ static ssize_t show_protocols(struct device *device, + if (dev->driver_type == RC_DRIVER_SCANCODE) { + enabled = dev->rc_map.rc_type; + allowed = dev->allowed_protos; +- } else { ++ } else if (dev->raw) { + enabled = dev->raw->enabled_protocols; + allowed = ir_raw_get_allowed_protocols(); ++ } else { ++ mutex_unlock(&dev->lock); ++ return -ENODEV; + } + + IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", +diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c +index ee0d0b3..d345215 100644 +--- a/drivers/media/video/omap/omap_vout.c ++++ b/drivers/media/video/omap/omap_vout.c +@@ -206,19 +206,21 @@ static u32 omap_vout_uservirt_to_phys(u32 virtp) + struct vm_area_struct *vma; + struct mm_struct *mm = current->mm; + +- vma = find_vma(mm, virtp); + /* For kernel direct-mapped memory, take the easy way */ +- if (virtp >= PAGE_OFFSET) { +- physp = virt_to_phys((void *) virtp); +- } else if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) { ++ if (virtp >= PAGE_OFFSET) ++ return virt_to_phys((void *) virtp); ++ ++ down_read(¤t->mm->mmap_sem); ++ vma = find_vma(mm, virtp); ++ if (vma && (vma->vm_flags & VM_IO) && vma->vm_pgoff) { + /* this will catch, kernel-allocated, mmaped-to-usermode + addresses */ + physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start); ++ up_read(¤t->mm->mmap_sem); + } else { + /* otherwise, use get_user_pages() for general userland pages */ + int res, nr_pages = 1; + struct page *pages; +- down_read(¤t->mm->mmap_sem); + + res = get_user_pages(current, current->mm, virtp, nr_pages, 1, + 0, &pages, NULL); +diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c +index 0edd618..8b0777f 100644 +--- a/drivers/media/video/v4l2-device.c ++++ b/drivers/media/video/v4l2-device.c +@@ -159,31 +159,21 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, + sd->v4l2_dev = v4l2_dev; + if (sd->internal_ops && sd->internal_ops->registered) { + err = sd->internal_ops->registered(sd); +- if (err) { +- module_put(sd->owner); +- return err; +- } ++ if (err) ++ goto error_module; + } + + /* This just returns 0 if either of the two args is NULL */ + err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler); +- if (err) { +- if (sd->internal_ops && sd->internal_ops->unregistered) +- sd->internal_ops->unregistered(sd); +- module_put(sd->owner); +- return err; +- } ++ if (err) ++ goto error_unregister; + + #if defined(CONFIG_MEDIA_CONTROLLER) + /* Register the entity. */ + if (v4l2_dev->mdev) { + err = media_device_register_entity(v4l2_dev->mdev, entity); +- if (err < 0) { +- if (sd->internal_ops && sd->internal_ops->unregistered) +- sd->internal_ops->unregistered(sd); +- module_put(sd->owner); +- return err; +- } ++ if (err < 0) ++ goto error_unregister; + } + #endif + +@@ -192,6 +182,14 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, + spin_unlock(&v4l2_dev->lock); + + return 0; ++ ++error_unregister: ++ if (sd->internal_ops && sd->internal_ops->unregistered) ++ sd->internal_ops->unregistered(sd); ++error_module: ++ module_put(sd->owner); ++ sd->v4l2_dev = NULL; ++ return err; + } + EXPORT_SYMBOL_GPL(v4l2_device_register_subdev); + +diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c +index 1b47937..85a074f 100644 +--- a/drivers/mmc/host/sdhci-esdhc-imx.c ++++ b/drivers/mmc/host/sdhci-esdhc-imx.c +@@ -232,15 +232,18 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg) + + static u16 esdhc_readw_le(struct sdhci_host *host, int reg) + { ++ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); ++ struct pltfm_imx_data *imx_data = pltfm_host->priv; ++ + if (unlikely(reg == SDHCI_HOST_VERSION)) { +- u16 val = readw(host->ioaddr + (reg ^ 2)); +- /* +- * uSDHC supports SDHCI v3.0, but it's encoded as value +- * 0x3 in host controller version register, which violates +- * SDHCI_SPEC_300 definition. Work it around here. +- */ +- if ((val & SDHCI_SPEC_VER_MASK) == 3) +- return --val; ++ reg ^= 2; ++ if (is_imx6q_usdhc(imx_data)) { ++ /* ++ * The usdhc register returns a wrong host version. ++ * Correct it here. ++ */ ++ return SDHCI_SPEC_300; ++ } + } + + return readw(host->ioaddr + reg); +diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c +index cf177b8..df5a09a 100644 +--- a/drivers/net/ethernet/intel/igb/igb_main.c ++++ b/drivers/net/ethernet/intel/igb/igb_main.c +@@ -4559,11 +4559,13 @@ void igb_update_stats(struct igb_adapter *adapter, + bytes = 0; + packets = 0; + for (i = 0; i < adapter->num_rx_queues; i++) { +- u32 rqdpc_tmp = rd32(E1000_RQDPC(i)) & 0x0FFF; ++ u32 rqdpc = rd32(E1000_RQDPC(i)); + struct igb_ring *ring = adapter->rx_ring[i]; + +- ring->rx_stats.drops += rqdpc_tmp; +- net_stats->rx_fifo_errors += rqdpc_tmp; ++ if (rqdpc) { ++ ring->rx_stats.drops += rqdpc; ++ net_stats->rx_fifo_errors += rqdpc; ++ } + + do { + start = u64_stats_fetch_begin_bh(&ring->rx_syncp); +diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h +index 315b96e..9fdd198 100644 +--- a/drivers/net/wireless/b43/dma.h ++++ b/drivers/net/wireless/b43/dma.h +@@ -169,7 +169,7 @@ struct b43_dmadesc_generic { + + /* DMA engine tuning knobs */ + #define B43_TXRING_SLOTS 256 +-#define B43_RXRING_SLOTS 64 ++#define B43_RXRING_SLOTS 256 + #define B43_DMA0_RX_FW598_BUFSIZE (B43_DMA0_RX_FW598_FO + IEEE80211_MAX_FRAME_LEN) + #define B43_DMA0_RX_FW351_BUFSIZE (B43_DMA0_RX_FW351_FO + IEEE80211_MAX_FRAME_LEN) + +diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c +index 7ca84c3..564218c 100644 +--- a/drivers/net/wireless/p54/p54usb.c ++++ b/drivers/net/wireless/p54/p54usb.c +@@ -84,8 +84,8 @@ static struct usb_device_id p54u_table[] = { + {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ + {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ + {USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */ +- {USB_DEVICE(0x083a, 0x4503)}, /* T-Com Sinus 154 data II */ + {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ ++ {USB_DEVICE(0x083a, 0x4531)}, /* T-Com Sinus 154 data II */ + {USB_DEVICE(0x083a, 0xc501)}, /* Zoom Wireless-G 4410 */ + {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */ + {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */ +diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +index a99be2d0..0984dcf 100644 +--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c ++++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +@@ -295,6 +295,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = { + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817f, rtl92cu_hal_cfg)}, + /* RTL8188CUS-VL */ + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x818a, rtl92cu_hal_cfg)}, ++ {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x819a, rtl92cu_hal_cfg)}, + /* 8188 Combo for BC4 */ + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8754, rtl92cu_hal_cfg)}, + +@@ -372,9 +373,15 @@ static struct usb_device_id rtl8192c_usb_ids[] = { + + MODULE_DEVICE_TABLE(usb, rtl8192c_usb_ids); + ++static int rtl8192cu_probe(struct usb_interface *intf, ++ const struct usb_device_id *id) ++{ ++ return rtl_usb_probe(intf, id, &rtl92cu_hal_cfg); ++} ++ + static struct usb_driver rtl8192cu_driver = { + .name = "rtl8192cu", +- .probe = rtl_usb_probe, ++ .probe = rtl8192cu_probe, + .disconnect = rtl_usb_disconnect, + .id_table = rtl8192c_usb_ids, + +diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c +index 30dd0a9..c04ee92 100644 +--- a/drivers/net/wireless/rtlwifi/usb.c ++++ b/drivers/net/wireless/rtlwifi/usb.c +@@ -44,8 +44,12 @@ + + static void usbctrl_async_callback(struct urb *urb) + { +- if (urb) +- kfree(urb->context); ++ if (urb) { ++ /* free dr */ ++ kfree(urb->setup_packet); ++ /* free databuf */ ++ kfree(urb->transfer_buffer); ++ } + } + + static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request, +@@ -57,38 +61,46 @@ static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request, + u8 reqtype; + struct usb_ctrlrequest *dr; + struct urb *urb; +- struct rtl819x_async_write_data { +- u8 data[REALTEK_USB_VENQT_MAX_BUF_SIZE]; +- struct usb_ctrlrequest dr; +- } *buf; ++ const u16 databuf_maxlen = REALTEK_USB_VENQT_MAX_BUF_SIZE; ++ u8 *databuf; ++ ++ if (WARN_ON_ONCE(len > databuf_maxlen)) ++ len = databuf_maxlen; + + pipe = usb_sndctrlpipe(udev, 0); /* write_out */ + reqtype = REALTEK_USB_VENQT_WRITE; + +- buf = kmalloc(sizeof(*buf), GFP_ATOMIC); +- if (!buf) ++ dr = kmalloc(sizeof(*dr), GFP_ATOMIC); ++ if (!dr) + return -ENOMEM; + ++ databuf = kmalloc(databuf_maxlen, GFP_ATOMIC); ++ if (!databuf) { ++ kfree(dr); ++ return -ENOMEM; ++ } ++ + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) { +- kfree(buf); ++ kfree(databuf); ++ kfree(dr); + return -ENOMEM; + } + +- dr = &buf->dr; +- + dr->bRequestType = reqtype; + dr->bRequest = request; + dr->wValue = cpu_to_le16(value); + dr->wIndex = cpu_to_le16(index); + dr->wLength = cpu_to_le16(len); +- memcpy(buf, pdata, len); ++ memcpy(databuf, pdata, len); + usb_fill_control_urb(urb, udev, pipe, +- (unsigned char *)dr, buf, len, +- usbctrl_async_callback, buf); ++ (unsigned char *)dr, databuf, len, ++ usbctrl_async_callback, NULL); + rc = usb_submit_urb(urb, GFP_ATOMIC); +- if (rc < 0) +- kfree(buf); ++ if (rc < 0) { ++ kfree(databuf); ++ kfree(dr); ++ } + usb_free_urb(urb); + return rc; + } +@@ -894,7 +906,8 @@ static struct rtl_intf_ops rtl_usb_ops = { + }; + + int __devinit rtl_usb_probe(struct usb_interface *intf, +- const struct usb_device_id *id) ++ const struct usb_device_id *id, ++ struct rtl_hal_cfg *rtl_hal_cfg) + { + int err; + struct ieee80211_hw *hw = NULL; +@@ -928,7 +941,7 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, + usb_set_intfdata(intf, hw); + /* init cfg & intf_ops */ + rtlpriv->rtlhal.interface = INTF_USB; +- rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_info); ++ rtlpriv->cfg = rtl_hal_cfg; + rtlpriv->intf_ops = &rtl_usb_ops; + rtl_dbgp_flag_init(hw); + /* Init IO handler */ +diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h +index d2a63fb..4dc4b1c 100644 +--- a/drivers/net/wireless/rtlwifi/usb.h ++++ b/drivers/net/wireless/rtlwifi/usb.h +@@ -158,7 +158,8 @@ struct rtl_usb_priv { + + + int __devinit rtl_usb_probe(struct usb_interface *intf, +- const struct usb_device_id *id); ++ const struct usb_device_id *id, ++ struct rtl_hal_cfg *rtl92cu_hal_cfg); + void rtl_usb_disconnect(struct usb_interface *intf); + int rtl_usb_suspend(struct usb_interface *pusb_intf, pm_message_t message); + int rtl_usb_resume(struct usb_interface *pusb_intf); +diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c +index 5925e0b..8eaf0e2 100644 +--- a/drivers/net/xen-netback/interface.c ++++ b/drivers/net/xen-netback/interface.c +@@ -132,6 +132,7 @@ static void xenvif_up(struct xenvif *vif) + static void xenvif_down(struct xenvif *vif) + { + disable_irq(vif->irq); ++ del_timer_sync(&vif->credit_timeout); + xen_netbk_deschedule_xenvif(vif); + xen_netbk_remove_xenvif(vif); + } +@@ -362,8 +363,6 @@ void xenvif_disconnect(struct xenvif *vif) + atomic_dec(&vif->refcnt); + wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0); + +- del_timer_sync(&vif->credit_timeout); +- + if (vif->irq) + unbind_from_irqhandler(vif->irq, vif); + +diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c +index b802bb3..185a0eb 100644 +--- a/drivers/net/xen-netback/netback.c ++++ b/drivers/net/xen-netback/netback.c +@@ -883,13 +883,13 @@ static int netbk_count_requests(struct xenvif *vif, + if (frags >= work_to_do) { + netdev_err(vif->dev, "Need more frags\n"); + netbk_fatal_tx_err(vif); +- return -frags; ++ return -ENODATA; + } + + if (unlikely(frags >= MAX_SKB_FRAGS)) { + netdev_err(vif->dev, "Too many frags\n"); + netbk_fatal_tx_err(vif); +- return -frags; ++ return -E2BIG; + } + + memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + frags), +@@ -897,7 +897,7 @@ static int netbk_count_requests(struct xenvif *vif, + if (txp->size > first->size) { + netdev_err(vif->dev, "Frag is bigger than frame.\n"); + netbk_fatal_tx_err(vif); +- return -frags; ++ return -EIO; + } + + first->size -= txp->size; +@@ -907,7 +907,7 @@ static int netbk_count_requests(struct xenvif *vif, + netdev_err(vif->dev, "txp->offset: %x, size: %u\n", + txp->offset, txp->size); + netbk_fatal_tx_err(vif); +- return -frags; ++ return -EINVAL; + } + } while ((txp++)->flags & XEN_NETTXF_more_data); + return frags; +diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c +index 7f87bee..f53da9e 100644 +--- a/drivers/pci/remove.c ++++ b/drivers/pci/remove.c +@@ -19,6 +19,8 @@ static void pci_free_resources(struct pci_dev *dev) + + static void pci_stop_dev(struct pci_dev *dev) + { ++ pci_pme_active(dev, false); ++ + if (dev->is_added) { + pci_proc_detach_device(dev); + pci_remove_sysfs_dev_files(dev); +diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c +index 86e4a1a..6bb02ab 100644 +--- a/drivers/pcmcia/vrc4171_card.c ++++ b/drivers/pcmcia/vrc4171_card.c +@@ -246,6 +246,7 @@ static int pccard_init(struct pcmcia_socket *sock) + socket = &vrc4171_sockets[slot]; + socket->csc_irq = search_nonuse_irq(); + socket->io_irq = search_nonuse_irq(); ++ spin_lock_init(&socket->lock); + + return 0; + } +diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c +index f75a4c8..3a09460 100644 +--- a/drivers/platform/x86/asus-laptop.c ++++ b/drivers/platform/x86/asus-laptop.c +@@ -820,8 +820,10 @@ static ssize_t show_infos(struct device *dev, + /* + * The HWRS method return informations about the hardware. + * 0x80 bit is for WLAN, 0x100 for Bluetooth. ++ * 0x40 for WWAN, 0x10 for WIMAX. + * The significance of others is yet to be found. +- * If we don't find the method, we assume the device are present. ++ * We don't currently use this for device detection, and it ++ * takes several seconds to run on some systems. + */ + rv = acpi_evaluate_integer(asus->handle, "HWRS", NULL, &temp); + if (!ACPI_FAILURE(rv)) +@@ -1591,7 +1593,7 @@ static int asus_laptop_get_info(struct asus_laptop *asus) + { + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *model = NULL; +- unsigned long long bsts_result, hwrs_result; ++ unsigned long long bsts_result; + char *string = NULL; + acpi_status status; + +@@ -1653,17 +1655,6 @@ static int asus_laptop_get_info(struct asus_laptop *asus) + if (*string) + pr_notice(" %s model detected\n", string); + +- /* +- * The HWRS method return informations about the hardware. +- * 0x80 bit is for WLAN, 0x100 for Bluetooth, +- * 0x40 for WWAN, 0x10 for WIMAX. +- * The significance of others is yet to be found. +- */ +- status = +- acpi_evaluate_integer(asus->handle, "HWRS", NULL, &hwrs_result); +- if (!ACPI_FAILURE(status)) +- pr_notice(" HWRS returned %x", (int)hwrs_result); +- + if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL)) + asus->have_rsts = true; + +diff --git a/drivers/pps/clients/pps-ldisc.c b/drivers/pps/clients/pps-ldisc.c +index 79451f2..60cee9e 100644 +--- a/drivers/pps/clients/pps-ldisc.c ++++ b/drivers/pps/clients/pps-ldisc.c +@@ -31,7 +31,7 @@ + static void pps_tty_dcd_change(struct tty_struct *tty, unsigned int status, + struct pps_event_time *ts) + { +- struct pps_device *pps = (struct pps_device *)tty->disc_data; ++ struct pps_device *pps = pps_lookup_dev(tty); + + BUG_ON(pps == NULL); + +@@ -67,9 +67,9 @@ static int pps_tty_open(struct tty_struct *tty) + pr_err("cannot register PPS source \"%s\"\n", info.path); + return -ENOMEM; + } +- tty->disc_data = pps; ++ pps->lookup_cookie = tty; + +- /* Should open N_TTY ldisc too */ ++ /* Now open the base class N_TTY ldisc */ + ret = alias_n_tty_open(tty); + if (ret < 0) { + pr_err("cannot open tty ldisc \"%s\"\n", info.path); +@@ -81,7 +81,6 @@ static int pps_tty_open(struct tty_struct *tty) + return 0; + + err_unregister: +- tty->disc_data = NULL; + pps_unregister_source(pps); + return ret; + } +@@ -90,11 +89,10 @@ static void (*alias_n_tty_close)(struct tty_struct *tty); + + static void pps_tty_close(struct tty_struct *tty) + { +- struct pps_device *pps = (struct pps_device *)tty->disc_data; ++ struct pps_device *pps = pps_lookup_dev(tty); + + alias_n_tty_close(tty); + +- tty->disc_data = NULL; + dev_info(pps->dev, "removed\n"); + pps_unregister_source(pps); + } +diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c +index 2baadd2..e83669f 100644 +--- a/drivers/pps/pps.c ++++ b/drivers/pps/pps.c +@@ -247,12 +247,15 @@ static int pps_cdev_open(struct inode *inode, struct file *file) + struct pps_device *pps = container_of(inode->i_cdev, + struct pps_device, cdev); + file->private_data = pps; +- ++ kobject_get(&pps->dev->kobj); + return 0; + } + + static int pps_cdev_release(struct inode *inode, struct file *file) + { ++ struct pps_device *pps = container_of(inode->i_cdev, ++ struct pps_device, cdev); ++ kobject_put(&pps->dev->kobj); + return 0; + } + +@@ -274,8 +277,10 @@ static void pps_device_destruct(struct device *dev) + { + struct pps_device *pps = dev_get_drvdata(dev); + +- /* release id here to protect others from using it while it's +- * still in use */ ++ cdev_del(&pps->cdev); ++ ++ /* Now we can release the ID for re-use */ ++ pr_debug("deallocating pps%d\n", pps->id); + mutex_lock(&pps_idr_lock); + idr_remove(&pps_idr, pps->id); + mutex_unlock(&pps_idr_lock); +@@ -330,6 +335,7 @@ int pps_register_cdev(struct pps_device *pps) + if (IS_ERR(pps->dev)) + goto del_cdev; + ++ /* Override the release function with our own */ + pps->dev->release = pps_device_destruct; + + pr_debug("source %s got cdev (%d:%d)\n", pps->info.name, +@@ -350,11 +356,44 @@ free_idr: + + void pps_unregister_cdev(struct pps_device *pps) + { ++ pr_debug("unregistering pps%d\n", pps->id); ++ pps->lookup_cookie = NULL; + device_destroy(pps_class, pps->dev->devt); +- cdev_del(&pps->cdev); + } + + /* ++ * Look up a pps device by magic cookie. ++ * The cookie is usually a pointer to some enclosing device, but this ++ * code doesn't care; you should never be dereferencing it. ++ * ++ * This is a bit of a kludge that is currently used only by the PPS ++ * serial line discipline. It may need to be tweaked when a second user ++ * is found. ++ * ++ * There is no function interface for setting the lookup_cookie field. ++ * It's initialized to NULL when the pps device is created, and if a ++ * client wants to use it, just fill it in afterward. ++ * ++ * The cookie is automatically set to NULL in pps_unregister_source() ++ * so that it will not be used again, even if the pps device cannot ++ * be removed from the idr due to pending references holding the minor ++ * number in use. ++ */ ++struct pps_device *pps_lookup_dev(void const *cookie) ++{ ++ struct pps_device *pps; ++ unsigned id; ++ ++ rcu_read_lock(); ++ idr_for_each_entry(&pps_idr, pps, id) ++ if (cookie == pps->lookup_cookie) ++ break; ++ rcu_read_unlock(); ++ return pps; ++} ++EXPORT_SYMBOL(pps_lookup_dev); ++ ++/* + * Module stuff + */ + +diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c +index 73816d8..1f94073 100644 +--- a/drivers/rtc/rtc-pl031.c ++++ b/drivers/rtc/rtc-pl031.c +@@ -344,7 +344,9 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) + /* Enable the clockwatch on ST Variants */ + if (ldata->hw_designer == AMBA_VENDOR_ST) + data |= RTC_CR_CWEN; +- writel(data | RTC_CR_EN, ldata->base + RTC_CR); ++ else ++ data |= RTC_CR_EN; ++ writel(data, ldata->base + RTC_CR); + + /* + * On ST PL031 variants, the RTC reset value does not provide correct +diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c +index 94f49ff..b1e8f6c 100644 +--- a/drivers/s390/kvm/kvm_virtio.c ++++ b/drivers/s390/kvm/kvm_virtio.c +@@ -414,6 +414,26 @@ static void kvm_extint_handler(unsigned int ext_int_code, + } + + /* ++ * For s390-virtio, we expect a page above main storage containing ++ * the virtio configuration. Try to actually load from this area ++ * in order to figure out if the host provides this page. ++ */ ++static int __init test_devices_support(unsigned long addr) ++{ ++ int ret = -EIO; ++ ++ asm volatile( ++ "0: lura 0,%1\n" ++ "1: xgr %0,%0\n" ++ "2:\n" ++ EX_TABLE(0b,2b) ++ EX_TABLE(1b,2b) ++ : "+d" (ret) ++ : "a" (addr) ++ : "0", "cc"); ++ return ret; ++} ++/* + * Init function for virtio + * devices are in a single page above top of "normal" mem + */ +@@ -424,21 +444,23 @@ static int __init kvm_devices_init(void) + if (!MACHINE_IS_KVM) + return -ENODEV; + ++ if (test_devices_support(real_memory_size) < 0) ++ return -ENODEV; ++ ++ rc = vmem_add_mapping(real_memory_size, PAGE_SIZE); ++ if (rc) ++ return rc; ++ ++ kvm_devices = (void *) real_memory_size; ++ + kvm_root = root_device_register("kvm_s390"); + if (IS_ERR(kvm_root)) { + rc = PTR_ERR(kvm_root); + printk(KERN_ERR "Could not register kvm_s390 root device"); ++ vmem_remove_mapping(real_memory_size, PAGE_SIZE); + return rc; + } + +- rc = vmem_add_mapping(real_memory_size, PAGE_SIZE); +- if (rc) { +- root_device_unregister(kvm_root); +- return rc; +- } +- +- kvm_devices = (void *) real_memory_size; +- + INIT_WORK(&hotplug_work, hotplug_devices); + + service_subclass_irq_register(); +diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c +index ab9f5ed..a023f52 100644 +--- a/drivers/staging/comedi/comedi_fops.c ++++ b/drivers/staging/comedi/comedi_fops.c +@@ -136,6 +136,11 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, + /* Device config is special, because it must work on + * an unconfigured device. */ + if (cmd == COMEDI_DEVCONFIG) { ++ if (minor >= COMEDI_NUM_BOARD_MINORS) { ++ /* Device config not appropriate on non-board minors. */ ++ rc = -ENOTTY; ++ goto done; ++ } + rc = do_devconfig_ioctl(dev, + (struct comedi_devconfig __user *)arg); + goto done; +@@ -1569,7 +1574,7 @@ static unsigned int comedi_poll(struct file *file, poll_table * wait) + + mask = 0; + read_subdev = comedi_get_read_subdevice(dev_file_info); +- if (read_subdev) { ++ if (read_subdev && read_subdev->async) { + poll_wait(file, &read_subdev->async->wait_head, wait); + if (!read_subdev->busy + || comedi_buf_read_n_available(read_subdev->async) > 0 +@@ -1579,7 +1584,7 @@ static unsigned int comedi_poll(struct file *file, poll_table * wait) + } + } + write_subdev = comedi_get_write_subdevice(dev_file_info); +- if (write_subdev) { ++ if (write_subdev && write_subdev->async) { + poll_wait(file, &write_subdev->async->wait_head, wait); + comedi_buf_write_alloc(write_subdev->async, + write_subdev->async->prealloc_bufsz); +@@ -1621,7 +1626,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, + } + + s = comedi_get_write_subdevice(dev_file_info); +- if (s == NULL) { ++ if (s == NULL || s->async == NULL) { + retval = -EIO; + goto done; + } +@@ -1732,7 +1737,7 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, + } + + s = comedi_get_read_subdevice(dev_file_info); +- if (s == NULL) { ++ if (s == NULL || s->async == NULL) { + retval = -EIO; + goto done; + } +diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c +index 721b2be..0517a23 100644 +--- a/drivers/staging/comedi/drivers/ni_labpc.c ++++ b/drivers/staging/comedi/drivers/ni_labpc.c +@@ -1264,7 +1264,9 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) + else + channel = CR_CHAN(cmd->chanlist[0]); + /* munge channel bits for differential / scan disabled mode */ +- if (labpc_ai_scan_mode(cmd) != MODE_SINGLE_CHAN && aref == AREF_DIFF) ++ if ((labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN || ++ labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN_INTERVAL) && ++ aref == AREF_DIFF) + channel *= 2; + devpriv->command1_bits |= ADC_CHAN_BITS(channel); + devpriv->command1_bits |= thisboard->ai_range_code[range]; +@@ -1280,21 +1282,6 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) + devpriv->write_byte(devpriv->command1_bits, + dev->iobase + COMMAND1_REG); + } +- /* setup any external triggering/pacing (command4 register) */ +- devpriv->command4_bits = 0; +- if (cmd->convert_src != TRIG_EXT) +- devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT; +- /* XXX should discard first scan when using interval scanning +- * since manual says it is not synced with scan clock */ +- if (labpc_use_continuous_mode(cmd) == 0) { +- devpriv->command4_bits |= INTERVAL_SCAN_EN_BIT; +- if (cmd->scan_begin_src == TRIG_EXT) +- devpriv->command4_bits |= EXT_SCAN_EN_BIT; +- } +- /* single-ended/differential */ +- if (aref == AREF_DIFF) +- devpriv->command4_bits |= ADC_DIFF_BIT; +- devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG); + + devpriv->write_byte(cmd->chanlist_len, + dev->iobase + INTERVAL_COUNT_REG); +@@ -1374,6 +1361,22 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) + devpriv->command3_bits &= ~ADC_FNE_INTR_EN_BIT; + devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG); + ++ /* setup any external triggering/pacing (command4 register) */ ++ devpriv->command4_bits = 0; ++ if (cmd->convert_src != TRIG_EXT) ++ devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT; ++ /* XXX should discard first scan when using interval scanning ++ * since manual says it is not synced with scan clock */ ++ if (labpc_use_continuous_mode(cmd) == 0) { ++ devpriv->command4_bits |= INTERVAL_SCAN_EN_BIT; ++ if (cmd->scan_begin_src == TRIG_EXT) ++ devpriv->command4_bits |= EXT_SCAN_EN_BIT; ++ } ++ /* single-ended/differential */ ++ if (aref == AREF_DIFF) ++ devpriv->command4_bits |= ADC_DIFF_BIT; ++ devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG); ++ + /* startup acquisition */ + + /* command2 reg */ +diff --git a/drivers/staging/speakup/speakup_soft.c b/drivers/staging/speakup/speakup_soft.c +index b5130c8..e2f5c81 100644 +--- a/drivers/staging/speakup/speakup_soft.c ++++ b/drivers/staging/speakup/speakup_soft.c +@@ -46,7 +46,7 @@ static int misc_registered; + static struct var_t vars[] = { + { CAPS_START, .u.s = {"\x01+3p" } }, + { CAPS_STOP, .u.s = {"\x01-3p" } }, +- { RATE, .u.n = {"\x01%ds", 5, 0, 9, 0, 0, NULL } }, ++ { RATE, .u.n = {"\x01%ds", 2, 0, 9, 0, 0, NULL } }, + { PITCH, .u.n = {"\x01%dp", 5, 0, 9, 0, 0, NULL } }, + { VOL, .u.n = {"\x01%dv", 5, 0, 9, 0, 0, NULL } }, + { TONE, .u.n = {"\x01%dx", 1, 0, 2, 0, 0, NULL } }, +diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c +index 09de99f..2594a31 100644 +--- a/drivers/staging/zram/zram_drv.c ++++ b/drivers/staging/zram/zram_drv.c +@@ -242,7 +242,7 @@ static int zram_bvec_read(struct zram *zram, struct bio_vec *bvec, + + if (is_partial_io(bvec)) { + /* Use a temporary buffer to decompress the page */ +- uncmem = kmalloc(PAGE_SIZE, GFP_KERNEL); ++ uncmem = kmalloc(PAGE_SIZE, GFP_NOIO); + if (!uncmem) { + pr_info("Error allocating temp memory!\n"); + return -ENOMEM; +@@ -338,7 +338,7 @@ static int zram_bvec_write(struct zram *zram, struct bio_vec *bvec, u32 index, + * This is a partial IO. We need to read the full page + * before to write the changes. + */ +- uncmem = kmalloc(PAGE_SIZE, GFP_KERNEL); ++ uncmem = kmalloc(PAGE_SIZE, GFP_NOIO); + if (!uncmem) { + pr_info("Error allocating temp memory!\n"); + ret = -ENOMEM; +diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c +index a0143a0..5def359 100644 +--- a/drivers/target/target_core_device.c ++++ b/drivers/target/target_core_device.c +@@ -1439,24 +1439,18 @@ static struct se_lun *core_dev_get_lun(struct se_portal_group *tpg, u32 unpacked + + struct se_lun_acl *core_dev_init_initiator_node_lun_acl( + struct se_portal_group *tpg, ++ struct se_node_acl *nacl, + u32 mapped_lun, +- char *initiatorname, + int *ret) + { + struct se_lun_acl *lacl; +- struct se_node_acl *nacl; + +- if (strlen(initiatorname) >= TRANSPORT_IQN_LEN) { ++ if (strlen(nacl->initiatorname) >= TRANSPORT_IQN_LEN) { + pr_err("%s InitiatorName exceeds maximum size.\n", + tpg->se_tpg_tfo->get_fabric_name()); + *ret = -EOVERFLOW; + return NULL; + } +- nacl = core_tpg_get_initiator_node_acl(tpg, initiatorname); +- if (!nacl) { +- *ret = -EINVAL; +- return NULL; +- } + lacl = kzalloc(sizeof(struct se_lun_acl), GFP_KERNEL); + if (!lacl) { + pr_err("Unable to allocate memory for struct se_lun_acl.\n"); +@@ -1467,7 +1461,8 @@ struct se_lun_acl *core_dev_init_initiator_node_lun_acl( + INIT_LIST_HEAD(&lacl->lacl_list); + lacl->mapped_lun = mapped_lun; + lacl->se_lun_nacl = nacl; +- snprintf(lacl->initiatorname, TRANSPORT_IQN_LEN, "%s", initiatorname); ++ snprintf(lacl->initiatorname, TRANSPORT_IQN_LEN, "%s", ++ nacl->initiatorname); + + return lacl; + } +diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c +index 09b6f87..60009bd 100644 +--- a/drivers/target/target_core_fabric_configfs.c ++++ b/drivers/target/target_core_fabric_configfs.c +@@ -354,9 +354,17 @@ static struct config_group *target_fabric_make_mappedlun( + ret = -EINVAL; + goto out; + } ++ if (mapped_lun > (TRANSPORT_MAX_LUNS_PER_TPG-1)) { ++ pr_err("Mapped LUN: %lu exceeds TRANSPORT_MAX_LUNS_PER_TPG" ++ "-1: %u for Target Portal Group: %u\n", mapped_lun, ++ TRANSPORT_MAX_LUNS_PER_TPG-1, ++ se_tpg->se_tpg_tfo->tpg_get_tag(se_tpg)); ++ ret = -EINVAL; ++ goto out; ++ } + +- lacl = core_dev_init_initiator_node_lun_acl(se_tpg, mapped_lun, +- config_item_name(acl_ci), &ret); ++ lacl = core_dev_init_initiator_node_lun_acl(se_tpg, se_nacl, ++ mapped_lun, &ret); + if (!lacl) { + ret = -EINVAL; + goto out; +diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c +index d91fe44..d048e33 100644 +--- a/drivers/target/target_core_tpg.c ++++ b/drivers/target/target_core_tpg.c +@@ -117,16 +117,10 @@ struct se_node_acl *core_tpg_get_initiator_node_acl( + struct se_node_acl *acl; + + spin_lock_irq(&tpg->acl_node_lock); +- list_for_each_entry(acl, &tpg->acl_node_list, acl_list) { +- if (!strcmp(acl->initiatorname, initiatorname) && +- !acl->dynamic_node_acl) { +- spin_unlock_irq(&tpg->acl_node_lock); +- return acl; +- } +- } ++ acl = __core_tpg_get_initiator_node_acl(tpg, initiatorname); + spin_unlock_irq(&tpg->acl_node_lock); + +- return NULL; ++ return acl; + } + + /* core_tpg_add_node_to_devs(): +diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c +index 90dad17..6748568 100644 +--- a/drivers/tty/serial/8250.c ++++ b/drivers/tty/serial/8250.c +@@ -2695,7 +2695,7 @@ serial8250_verify_port(struct uart_port *port, struct serial_struct *ser) + if (ser->irq >= nr_irqs || ser->irq < 0 || + ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || + ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS || +- ser->type == PORT_STARTECH) ++ ser->type == PORT_STARTECH || uart_config[ser->type].name == NULL) + return -EINVAL; + return 0; + } +@@ -2705,7 +2705,7 @@ serial8250_type(struct uart_port *port) + { + int type = port->type; + +- if (type >= ARRAY_SIZE(uart_config)) ++ if (type >= ARRAY_SIZE(uart_config) || uart_config[type].name == NULL) + type = 0; + return uart_config[type].name; + } +diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c +index 9314d93..937f927 100644 +--- a/drivers/tty/tty_ioctl.c ++++ b/drivers/tty/tty_ioctl.c +@@ -618,7 +618,7 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt) + if (opt & TERMIOS_WAIT) { + tty_wait_until_sent(tty, 0); + if (signal_pending(current)) +- return -EINTR; ++ return -ERESTARTSYS; + } + + tty_set_termios(tty, &tmp_termios); +@@ -685,7 +685,7 @@ static int set_termiox(struct tty_struct *tty, void __user *arg, int opt) + if (opt & TERMIOS_WAIT) { + tty_wait_until_sent(tty, 0); + if (signal_pending(current)) +- return -EINTR; ++ return -ERESTARTSYS; + } + + mutex_lock(&tty->termios_mutex); +diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c +index e716839..632df54 100644 +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -657,7 +657,7 @@ static inline void save_screen(struct vc_data *vc) + * Redrawing of screen + */ + +-static void clear_buffer_attributes(struct vc_data *vc) ++void clear_buffer_attributes(struct vc_data *vc) + { + unsigned short *p = (unsigned short *)vc->vc_origin; + int count = vc->vc_screenbuf_size / 2; +@@ -3016,7 +3016,7 @@ int __init vty_init(const struct file_operations *console_fops) + + static struct class *vtconsole_class; + +-static int bind_con_driver(const struct consw *csw, int first, int last, ++static int do_bind_con_driver(const struct consw *csw, int first, int last, + int deflt) + { + struct module *owner = csw->owner; +@@ -3027,7 +3027,7 @@ static int bind_con_driver(const struct consw *csw, int first, int last, + if (!try_module_get(owner)) + return -ENODEV; + +- console_lock(); ++ WARN_CONSOLE_UNLOCKED(); + + /* check if driver is registered */ + for (i = 0; i < MAX_NR_CON_DRIVER; i++) { +@@ -3112,11 +3112,22 @@ static int bind_con_driver(const struct consw *csw, int first, int last, + + retval = 0; + err: +- console_unlock(); + module_put(owner); + return retval; + }; + ++ ++static int bind_con_driver(const struct consw *csw, int first, int last, ++ int deflt) ++{ ++ int ret; ++ ++ console_lock(); ++ ret = do_bind_con_driver(csw, first, last, deflt); ++ console_unlock(); ++ return ret; ++} ++ + #ifdef CONFIG_VT_HW_CONSOLE_BINDING + static int con_is_graphics(const struct consw *csw, int first, int last) + { +@@ -3153,6 +3164,18 @@ static int con_is_graphics(const struct consw *csw, int first, int last) + */ + int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) + { ++ int retval; ++ ++ console_lock(); ++ retval = do_unbind_con_driver(csw, first, last, deflt); ++ console_unlock(); ++ return retval; ++} ++EXPORT_SYMBOL(unbind_con_driver); ++ ++/* unlocked version of unbind_con_driver() */ ++int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt) ++{ + struct module *owner = csw->owner; + const struct consw *defcsw = NULL; + struct con_driver *con_driver = NULL, *con_back = NULL; +@@ -3161,7 +3184,7 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) + if (!try_module_get(owner)) + return -ENODEV; + +- console_lock(); ++ WARN_CONSOLE_UNLOCKED(); + + /* check if driver is registered and if it is unbindable */ + for (i = 0; i < MAX_NR_CON_DRIVER; i++) { +@@ -3174,10 +3197,8 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) + } + } + +- if (retval) { +- console_unlock(); ++ if (retval) + goto err; +- } + + retval = -ENODEV; + +@@ -3193,15 +3214,11 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) + } + } + +- if (retval) { +- console_unlock(); ++ if (retval) + goto err; +- } + +- if (!con_is_bound(csw)) { +- console_unlock(); ++ if (!con_is_bound(csw)) + goto err; +- } + + first = max(first, con_driver->first); + last = min(last, con_driver->last); +@@ -3228,15 +3245,14 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) + if (!con_is_bound(csw)) + con_driver->flag &= ~CON_DRIVER_FLAG_INIT; + +- console_unlock(); + /* ignore return value, binding should not fail */ +- bind_con_driver(defcsw, first, last, deflt); ++ do_bind_con_driver(defcsw, first, last, deflt); + err: + module_put(owner); + return retval; + + } +-EXPORT_SYMBOL(unbind_con_driver); ++EXPORT_SYMBOL_GPL(do_unbind_con_driver); + + static int vt_bind(struct con_driver *con) + { +@@ -3508,28 +3524,18 @@ int con_debug_leave(void) + } + EXPORT_SYMBOL_GPL(con_debug_leave); + +-/** +- * register_con_driver - register console driver to console layer +- * @csw: console driver +- * @first: the first console to take over, minimum value is 0 +- * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1 +- * +- * DESCRIPTION: This function registers a console driver which can later +- * bind to a range of consoles specified by @first and @last. It will +- * also initialize the console driver by calling con_startup(). +- */ +-int register_con_driver(const struct consw *csw, int first, int last) ++static int do_register_con_driver(const struct consw *csw, int first, int last) + { + struct module *owner = csw->owner; + struct con_driver *con_driver; + const char *desc; + int i, retval = 0; + ++ WARN_CONSOLE_UNLOCKED(); ++ + if (!try_module_get(owner)) + return -ENODEV; + +- console_lock(); +- + for (i = 0; i < MAX_NR_CON_DRIVER; i++) { + con_driver = ®istered_con_driver[i]; + +@@ -3582,10 +3588,29 @@ int register_con_driver(const struct consw *csw, int first, int last) + } + + err: +- console_unlock(); + module_put(owner); + return retval; + } ++ ++/** ++ * register_con_driver - register console driver to console layer ++ * @csw: console driver ++ * @first: the first console to take over, minimum value is 0 ++ * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1 ++ * ++ * DESCRIPTION: This function registers a console driver which can later ++ * bind to a range of consoles specified by @first and @last. It will ++ * also initialize the console driver by calling con_startup(). ++ */ ++int register_con_driver(const struct consw *csw, int first, int last) ++{ ++ int retval; ++ ++ console_lock(); ++ retval = do_register_con_driver(csw, first, last); ++ console_unlock(); ++ return retval; ++} + EXPORT_SYMBOL(register_con_driver); + + /** +@@ -3601,9 +3626,18 @@ EXPORT_SYMBOL(register_con_driver); + */ + int unregister_con_driver(const struct consw *csw) + { +- int i, retval = -ENODEV; ++ int retval; + + console_lock(); ++ retval = do_unregister_con_driver(csw); ++ console_unlock(); ++ return retval; ++} ++EXPORT_SYMBOL(unregister_con_driver); ++ ++int do_unregister_con_driver(const struct consw *csw) ++{ ++ int i, retval = -ENODEV; + + /* cannot unregister a bound driver */ + if (con_is_bound(csw)) +@@ -3629,27 +3663,53 @@ int unregister_con_driver(const struct consw *csw) + } + } + err: +- console_unlock(); + return retval; + } +-EXPORT_SYMBOL(unregister_con_driver); ++EXPORT_SYMBOL_GPL(do_unregister_con_driver); + + /* + * If we support more console drivers, this function is used + * when a driver wants to take over some existing consoles + * and become default driver for newly opened ones. + * +- * take_over_console is basically a register followed by unbind ++ * take_over_console is basically a register followed by unbind ++ */ ++int do_take_over_console(const struct consw *csw, int first, int last, int deflt) ++{ ++ int err; ++ ++ err = do_register_con_driver(csw, first, last); ++ /* ++ * If we get an busy error we still want to bind the console driver ++ * and return success, as we may have unbound the console driver ++ * but not unregistered it. ++ */ ++ if (err == -EBUSY) ++ err = 0; ++ if (!err) ++ do_bind_con_driver(csw, first, last, deflt); ++ ++ return err; ++} ++EXPORT_SYMBOL_GPL(do_take_over_console); ++ ++/* ++ * If we support more console drivers, this function is used ++ * when a driver wants to take over some existing consoles ++ * and become default driver for newly opened ones. ++ * ++ * take_over_console is basically a register followed by unbind + */ + int take_over_console(const struct consw *csw, int first, int last, int deflt) + { + int err; + + err = register_con_driver(csw, first, last); +- /* if we get an busy error we still want to bind the console driver ++ /* ++ * If we get an busy error we still want to bind the console driver + * and return success, as we may have unbound the console driver +- * but not unregistered it. +- */ ++ * but not unregistered it. ++ */ + if (err == -EBUSY) + err = 0; + if (!err) +diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c +index c77f0d6..9f3003e 100644 +--- a/drivers/usb/core/driver.c ++++ b/drivers/usb/core/driver.c +@@ -541,22 +541,10 @@ int usb_match_device(struct usb_device *dev, const struct usb_device_id *id) + } + + /* returns 0 if no match, 1 if match */ +-int usb_match_one_id(struct usb_interface *interface, +- const struct usb_device_id *id) ++int usb_match_one_id_intf(struct usb_device *dev, ++ struct usb_host_interface *intf, ++ const struct usb_device_id *id) + { +- struct usb_host_interface *intf; +- struct usb_device *dev; +- +- /* proc_connectinfo in devio.c may call us with id == NULL. */ +- if (id == NULL) +- return 0; +- +- intf = interface->cur_altsetting; +- dev = interface_to_usbdev(interface); +- +- if (!usb_match_device(dev, id)) +- return 0; +- + /* The interface class, subclass, and protocol should never be + * checked for a match if the device class is Vendor Specific, + * unless the match record specifies the Vendor ID. */ +@@ -581,6 +569,26 @@ int usb_match_one_id(struct usb_interface *interface, + + return 1; + } ++ ++/* returns 0 if no match, 1 if match */ ++int usb_match_one_id(struct usb_interface *interface, ++ const struct usb_device_id *id) ++{ ++ struct usb_host_interface *intf; ++ struct usb_device *dev; ++ ++ /* proc_connectinfo in devio.c may call us with id == NULL. */ ++ if (id == NULL) ++ return 0; ++ ++ intf = interface->cur_altsetting; ++ dev = interface_to_usbdev(interface); ++ ++ if (!usb_match_device(dev, id)) ++ return 0; ++ ++ return usb_match_one_id_intf(dev, intf, id); ++} + EXPORT_SYMBOL_GPL(usb_match_one_id); + + /** +diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c +index 0ff8e9a..2564d8d 100644 +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -1883,7 +1883,7 @@ static int usb_enumerate_device(struct usb_device *udev) + if (err < 0) { + dev_err(&udev->dev, "can't read configurations, error %d\n", + err); +- goto fail; ++ return err; + } + } + if (udev->wusb == 1 && udev->authorized == 0) { +@@ -1899,8 +1899,12 @@ static int usb_enumerate_device(struct usb_device *udev) + udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber); + } + err = usb_enumerate_device_otg(udev); +-fail: +- return err; ++ if (err < 0) ++ return err; ++ ++ usb_detect_interface_quirks(udev); ++ ++ return 0; + } + + +diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c +index 3f08c09..0aaa4f1 100644 +--- a/drivers/usb/core/quirks.c ++++ b/drivers/usb/core/quirks.c +@@ -15,17 +15,22 @@ + #include <linux/usb/quirks.h> + #include "usb.h" + +-/* List of quirky USB devices. Please keep this list ordered by: ++/* Lists of quirky USB devices, split in device quirks and interface quirks. ++ * Device quirks are applied at the very beginning of the enumeration process, ++ * right after reading the device descriptor. They can thus only match on device ++ * information. ++ * ++ * Interface quirks are applied after reading all the configuration descriptors. ++ * They can match on both device and interface information. ++ * ++ * Note that the DELAY_INIT and HONOR_BNUMINTERFACES quirks do not make sense as ++ * interface quirks, as they only influence the enumeration process which is run ++ * before processing the interface quirks. ++ * ++ * Please keep the lists ordered by: + * 1) Vendor ID + * 2) Product ID + * 3) Class ID +- * +- * as we want specific devices to be overridden first, and only after that, any +- * class specific quirks. +- * +- * Right now the logic aborts if it finds a valid device in the table, we might +- * want to change that in the future if it turns out that a whole class of +- * devices is broken... + */ + static const struct usb_device_id usb_quirk_list[] = { + /* CBM - Flash disk */ +@@ -41,53 +46,23 @@ static const struct usb_device_id usb_quirk_list[] = { + /* Microsoft LifeCam-VX700 v2.0 */ + { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME }, + +- /* Logitech Webcam C200 */ +- { USB_DEVICE(0x046d, 0x0802), .driver_info = USB_QUIRK_RESET_RESUME }, +- +- /* Logitech Webcam C250 */ +- { USB_DEVICE(0x046d, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME }, +- +- /* Logitech Webcam C300 */ +- { USB_DEVICE(0x046d, 0x0805), .driver_info = USB_QUIRK_RESET_RESUME }, +- +- /* Logitech Webcam B/C500 */ +- { USB_DEVICE(0x046d, 0x0807), .driver_info = USB_QUIRK_RESET_RESUME }, +- +- /* Logitech Webcam C600 */ +- { USB_DEVICE(0x046d, 0x0808), .driver_info = USB_QUIRK_RESET_RESUME }, +- +- /* Logitech Webcam Pro 9000 */ +- { USB_DEVICE(0x046d, 0x0809), .driver_info = USB_QUIRK_RESET_RESUME }, ++ /* Logitech Quickcam Fusion */ ++ { USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME }, + +- /* Logitech Webcam C905 */ +- { USB_DEVICE(0x046d, 0x080a), .driver_info = USB_QUIRK_RESET_RESUME }, ++ /* Logitech Quickcam Orbit MP */ ++ { USB_DEVICE(0x046d, 0x08c2), .driver_info = USB_QUIRK_RESET_RESUME }, + +- /* Logitech Webcam C210 */ +- { USB_DEVICE(0x046d, 0x0819), .driver_info = USB_QUIRK_RESET_RESUME }, ++ /* Logitech Quickcam Pro for Notebook */ ++ { USB_DEVICE(0x046d, 0x08c3), .driver_info = USB_QUIRK_RESET_RESUME }, + +- /* Logitech Webcam C260 */ +- { USB_DEVICE(0x046d, 0x081a), .driver_info = USB_QUIRK_RESET_RESUME }, ++ /* Logitech Quickcam Pro 5000 */ ++ { USB_DEVICE(0x046d, 0x08c5), .driver_info = USB_QUIRK_RESET_RESUME }, + +- /* Logitech Webcam C310 */ +- { USB_DEVICE(0x046d, 0x081b), .driver_info = USB_QUIRK_RESET_RESUME }, ++ /* Logitech Quickcam OEM Dell Notebook */ ++ { USB_DEVICE(0x046d, 0x08c6), .driver_info = USB_QUIRK_RESET_RESUME }, + +- /* Logitech Webcam C910 */ +- { USB_DEVICE(0x046d, 0x0821), .driver_info = USB_QUIRK_RESET_RESUME }, +- +- /* Logitech Webcam C160 */ +- { USB_DEVICE(0x046d, 0x0824), .driver_info = USB_QUIRK_RESET_RESUME }, +- +- /* Logitech Webcam C270 */ +- { USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME }, +- +- /* Logitech Quickcam Pro 9000 */ +- { USB_DEVICE(0x046d, 0x0990), .driver_info = USB_QUIRK_RESET_RESUME }, +- +- /* Logitech Quickcam E3500 */ +- { USB_DEVICE(0x046d, 0x09a4), .driver_info = USB_QUIRK_RESET_RESUME }, +- +- /* Logitech Quickcam Vision Pro */ +- { USB_DEVICE(0x046d, 0x09a6), .driver_info = USB_QUIRK_RESET_RESUME }, ++ /* Logitech Quickcam OEM Cisco VT Camera II */ ++ { USB_DEVICE(0x046d, 0x08c7), .driver_info = USB_QUIRK_RESET_RESUME }, + + /* Logitech Harmony 700-series */ + { USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT }, +@@ -163,16 +138,57 @@ static const struct usb_device_id usb_quirk_list[] = { + { } /* terminating entry must be last */ + }; + +-static const struct usb_device_id *find_id(struct usb_device *udev) ++static const struct usb_device_id usb_interface_quirk_list[] = { ++ /* Logitech UVC Cameras */ ++ { USB_VENDOR_AND_INTERFACE_INFO(0x046d, USB_CLASS_VIDEO, 1, 0), ++ .driver_info = USB_QUIRK_RESET_RESUME }, ++ ++ { } /* terminating entry must be last */ ++}; ++ ++static bool usb_match_any_interface(struct usb_device *udev, ++ const struct usb_device_id *id) + { +- const struct usb_device_id *id = usb_quirk_list; ++ unsigned int i; + +- for (; id->idVendor || id->bDeviceClass || id->bInterfaceClass || +- id->driver_info; id++) { +- if (usb_match_device(udev, id)) +- return id; ++ for (i = 0; i < udev->descriptor.bNumConfigurations; ++i) { ++ struct usb_host_config *cfg = &udev->config[i]; ++ unsigned int j; ++ ++ for (j = 0; j < cfg->desc.bNumInterfaces; ++j) { ++ struct usb_interface_cache *cache; ++ struct usb_host_interface *intf; ++ ++ cache = cfg->intf_cache[j]; ++ if (cache->num_altsetting == 0) ++ continue; ++ ++ intf = &cache->altsetting[0]; ++ if (usb_match_one_id_intf(udev, intf, id)) ++ return true; ++ } ++ } ++ ++ return false; ++} ++ ++static u32 __usb_detect_quirks(struct usb_device *udev, ++ const struct usb_device_id *id) ++{ ++ u32 quirks = 0; ++ ++ for (; id->match_flags; id++) { ++ if (!usb_match_device(udev, id)) ++ continue; ++ ++ if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_INFO) && ++ !usb_match_any_interface(udev, id)) ++ continue; ++ ++ quirks |= (u32)(id->driver_info); + } +- return NULL; ++ ++ return quirks; + } + + /* +@@ -180,14 +196,10 @@ static const struct usb_device_id *find_id(struct usb_device *udev) + */ + void usb_detect_quirks(struct usb_device *udev) + { +- const struct usb_device_id *id = usb_quirk_list; +- +- id = find_id(udev); +- if (id) +- udev->quirks = (u32)(id->driver_info); ++ udev->quirks = __usb_detect_quirks(udev, usb_quirk_list); + if (udev->quirks) + dev_dbg(&udev->dev, "USB quirks for this device: %x\n", +- udev->quirks); ++ udev->quirks); + + /* For the present, all devices default to USB-PERSIST enabled */ + #if 0 /* was: #ifdef CONFIG_PM */ +@@ -204,3 +216,16 @@ void usb_detect_quirks(struct usb_device *udev) + udev->persist_enabled = 1; + #endif /* CONFIG_PM */ + } ++ ++void usb_detect_interface_quirks(struct usb_device *udev) ++{ ++ u32 quirks; ++ ++ quirks = __usb_detect_quirks(udev, usb_interface_quirk_list); ++ if (quirks == 0) ++ return; ++ ++ dev_dbg(&udev->dev, "USB interface quirks for this device: %x\n", ++ quirks); ++ udev->quirks |= quirks; ++} +diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h +index 45e8479..3e1159b 100644 +--- a/drivers/usb/core/usb.h ++++ b/drivers/usb/core/usb.h +@@ -24,6 +24,7 @@ extern void usb_disable_device(struct usb_device *dev, int skip_ep0); + extern int usb_deauthorize_device(struct usb_device *); + extern int usb_authorize_device(struct usb_device *); + extern void usb_detect_quirks(struct usb_device *udev); ++extern void usb_detect_interface_quirks(struct usb_device *udev); + extern int usb_remove_device(struct usb_device *udev); + + extern int usb_get_device_descriptor(struct usb_device *dev, +@@ -35,6 +36,9 @@ extern int usb_set_configuration(struct usb_device *dev, int configuration); + extern int usb_choose_configuration(struct usb_device *udev); + + extern void usb_kick_khubd(struct usb_device *dev); ++extern int usb_match_one_id_intf(struct usb_device *dev, ++ struct usb_host_interface *intf, ++ const struct usb_device_id *id); + extern int usb_match_device(struct usb_device *dev, + const struct usb_device_id *id); + extern void usb_forced_unbind_intf(struct usb_interface *intf); +diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c +index e39b029..d4159b8 100644 +--- a/drivers/usb/host/ehci-omap.c ++++ b/drivers/usb/host/ehci-omap.c +@@ -337,7 +337,7 @@ static const struct hc_driver ehci_omap_hc_driver = { + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, + }; + +-MODULE_ALIAS("platform:omap-ehci"); ++MODULE_ALIAS("platform:ehci-omap"); + MODULE_AUTHOR("Texas Instruments, Inc."); + MODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>"); + +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index d644a66..71c4696 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -1916,24 +1916,22 @@ static void ftdi_dtr_rts(struct usb_serial_port *port, int on) + { + struct ftdi_private *priv = usb_get_serial_port_data(port); + +- mutex_lock(&port->serial->disc_mutex); +- if (!port->serial->disconnected) { +- /* Disable flow control */ +- if (!on && usb_control_msg(port->serial->dev, ++ /* Disable flow control */ ++ if (!on) { ++ if (usb_control_msg(port->serial->dev, + usb_sndctrlpipe(port->serial->dev, 0), + FTDI_SIO_SET_FLOW_CTRL_REQUEST, + FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE, + 0, priv->interface, NULL, 0, + WDR_TIMEOUT) < 0) { +- dev_err(&port->dev, "error from flowcontrol urb\n"); ++ dev_err(&port->dev, "error from flowcontrol urb\n"); + } +- /* drop RTS and DTR */ +- if (on) +- set_mctrl(port, TIOCM_DTR | TIOCM_RTS); +- else +- clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); + } +- mutex_unlock(&port->serial->disc_mutex); ++ /* drop RTS and DTR */ ++ if (on) ++ set_mctrl(port, TIOCM_DTR | TIOCM_RTS); ++ else ++ clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); + } + + /* +diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c +index d3addb2..de0bb8e 100644 +--- a/drivers/usb/serial/mct_u232.c ++++ b/drivers/usb/serial/mct_u232.c +@@ -558,19 +558,15 @@ static void mct_u232_dtr_rts(struct usb_serial_port *port, int on) + unsigned int control_state; + struct mct_u232_private *priv = usb_get_serial_port_data(port); + +- mutex_lock(&port->serial->disc_mutex); +- if (!port->serial->disconnected) { +- /* drop DTR and RTS */ +- spin_lock_irq(&priv->lock); +- if (on) +- priv->control_state |= TIOCM_DTR | TIOCM_RTS; +- else +- priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); +- control_state = priv->control_state; +- spin_unlock_irq(&priv->lock); +- mct_u232_set_modem_ctrl(port->serial, control_state); +- } +- mutex_unlock(&port->serial->disc_mutex); ++ spin_lock_irq(&priv->lock); ++ if (on) ++ priv->control_state |= TIOCM_DTR | TIOCM_RTS; ++ else ++ priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS); ++ control_state = priv->control_state; ++ spin_unlock_irq(&priv->lock); ++ ++ mct_u232_set_modem_ctrl(port->serial, control_state); + } + + static void mct_u232_close(struct usb_serial_port *port) +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index 52cd814..24a3ea6 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -479,6 +479,7 @@ static const struct option_blacklist_info four_g_w14_blacklist = { + + static const struct option_blacklist_info alcatel_x200_blacklist = { + .sendsetup = BIT(0) | BIT(1), ++ .reserved = BIT(4), + }; + + static const struct option_blacklist_info zte_0037_blacklist = { +@@ -575,8 +576,14 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, + { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, + { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, ++ { USB_DEVICE(QUANTA_VENDOR_ID, 0xea42), ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c05, USB_CLASS_COMM, 0x02, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1441, USB_CLASS_COMM, 0x02, 0xff) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1442, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), +@@ -1215,7 +1222,14 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), + .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist + }, +- { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D) }, ++ { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D), ++ .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, ++ { USB_DEVICE(ALCATEL_VENDOR_ID, 0x0052), ++ .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, ++ { USB_DEVICE(ALCATEL_VENDOR_ID, 0x00b6), ++ .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ { USB_DEVICE(ALCATEL_VENDOR_ID, 0x00b7), ++ .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L100V), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, +diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c +index e1f1ebd..a7fa673 100644 +--- a/drivers/usb/serial/sierra.c ++++ b/drivers/usb/serial/sierra.c +@@ -891,19 +891,13 @@ static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port) + + static void sierra_dtr_rts(struct usb_serial_port *port, int on) + { +- struct usb_serial *serial = port->serial; + struct sierra_port_private *portdata; + + portdata = usb_get_serial_port_data(port); + portdata->rts_state = on; + portdata->dtr_state = on; + +- if (serial->dev) { +- mutex_lock(&serial->disc_mutex); +- if (!serial->disconnected) +- sierra_send_setup(port); +- mutex_unlock(&serial->disc_mutex); +- } ++ sierra_send_setup(port); + } + + static int sierra_startup(struct usb_serial *serial) +diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c +index 87362e4..fff7f17 100644 +--- a/drivers/usb/serial/ssu100.c ++++ b/drivers/usb/serial/ssu100.c +@@ -533,19 +533,16 @@ static void ssu100_dtr_rts(struct usb_serial_port *port, int on) + + dbg("%s\n", __func__); + +- mutex_lock(&port->serial->disc_mutex); +- if (!port->serial->disconnected) { +- /* Disable flow control */ +- if (!on && +- ssu100_setregister(dev, 0, UART_MCR, 0) < 0) ++ /* Disable flow control */ ++ if (!on) { ++ if (ssu100_setregister(dev, 0, UART_MCR, 0) < 0) + dev_err(&port->dev, "error from flowcontrol urb\n"); +- /* drop RTS and DTR */ +- if (on) +- set_mctrl(dev, TIOCM_DTR | TIOCM_RTS); +- else +- clear_mctrl(dev, TIOCM_DTR | TIOCM_RTS); + } +- mutex_unlock(&port->serial->disc_mutex); ++ /* drop RTS and DTR */ ++ if (on) ++ set_mctrl(dev, TIOCM_DTR | TIOCM_RTS); ++ else ++ clear_mctrl(dev, TIOCM_DTR | TIOCM_RTS); + } + + static void ssu100_update_msr(struct usb_serial_port *port, u8 msr) +diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c +index e5206de..dc1ce62 100644 +--- a/drivers/usb/serial/usb-serial.c ++++ b/drivers/usb/serial/usb-serial.c +@@ -697,9 +697,20 @@ static int serial_carrier_raised(struct tty_port *port) + static void serial_dtr_rts(struct tty_port *port, int on) + { + struct usb_serial_port *p = container_of(port, struct usb_serial_port, port); +- struct usb_serial_driver *drv = p->serial->type; +- if (drv->dtr_rts) ++ struct usb_serial *serial = p->serial; ++ struct usb_serial_driver *drv = serial->type; ++ ++ if (!drv->dtr_rts) ++ return; ++ /* ++ * Work-around bug in the tty-layer which can result in dtr_rts ++ * being called after a disconnect (and tty_unregister_device ++ * has returned). Remove once bug has been squashed. ++ */ ++ mutex_lock(&serial->disc_mutex); ++ if (!serial->disconnected) + drv->dtr_rts(p, on); ++ mutex_unlock(&serial->disc_mutex); + } + + static const struct tty_port_operations serial_port_ops = { +diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c +index d555ca9..6c92301 100644 +--- a/drivers/usb/serial/usb_wwan.c ++++ b/drivers/usb/serial/usb_wwan.c +@@ -41,7 +41,6 @@ static int debug; + + void usb_wwan_dtr_rts(struct usb_serial_port *port, int on) + { +- struct usb_serial *serial = port->serial; + struct usb_wwan_port_private *portdata; + + struct usb_wwan_intf_private *intfdata; +@@ -54,12 +53,11 @@ void usb_wwan_dtr_rts(struct usb_serial_port *port, int on) + return; + + portdata = usb_get_serial_port_data(port); +- mutex_lock(&serial->disc_mutex); ++ /* FIXME: locking */ + portdata->rts_state = on; + portdata->dtr_state = on; +- if (serial->dev) +- intfdata->send_setup(port); +- mutex_unlock(&serial->disc_mutex); ++ ++ intfdata->send_setup(port); + } + EXPORT_SYMBOL(usb_wwan_dtr_rts); + +diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c +index 16b0bf0..7ab9046 100644 +--- a/drivers/usb/storage/initializers.c ++++ b/drivers/usb/storage/initializers.c +@@ -147,7 +147,7 @@ static int usb_stor_huawei_dongles_pid(struct us_data *us) + int idProduct; + + idesc = &us->pusb_intf->cur_altsetting->desc; +- idProduct = us->pusb_dev->descriptor.idProduct; ++ idProduct = le16_to_cpu(us->pusb_dev->descriptor.idProduct); + /* The first port is CDROM, + * means the dongle in the single port mode, + * and a switch command is required to be sent. */ +@@ -169,7 +169,7 @@ int usb_stor_huawei_init(struct us_data *us) + int result = 0; + + if (usb_stor_huawei_dongles_pid(us)) { +- if (us->pusb_dev->descriptor.idProduct >= 0x1446) ++ if (le16_to_cpu(us->pusb_dev->descriptor.idProduct) >= 0x1446) + result = usb_stor_huawei_scsi_init(us); + else + result = usb_stor_huawei_feature_init(us); +diff --git a/drivers/usb/storage/unusual_cypress.h b/drivers/usb/storage/unusual_cypress.h +index 2c85530..65a6a75 100644 +--- a/drivers/usb/storage/unusual_cypress.h ++++ b/drivers/usb/storage/unusual_cypress.h +@@ -31,7 +31,7 @@ UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999, + "Cypress ISD-300LP", + USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), + +-UNUSUAL_DEV( 0x14cd, 0x6116, 0x0000, 0x9999, ++UNUSUAL_DEV( 0x14cd, 0x6116, 0x0000, 0x0219, + "Super Top", + "USB 2.0 SATA BRIDGE", + USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), +diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c +index ae66278..be32b1b 100644 +--- a/drivers/vhost/vhost.c ++++ b/drivers/vhost/vhost.c +@@ -1073,7 +1073,7 @@ static int translate_desc(struct vhost_dev *dev, u64 addr, u32 len, + } + _iov = iov + ret; + size = reg->memory_size - addr + reg->guest_phys_addr; +- _iov->iov_len = min((u64)len, size); ++ _iov->iov_len = min((u64)len - s, size); + _iov->iov_base = (void __user *)(unsigned long) + (reg->userspace_addr + addr - reg->guest_phys_addr); + s += size; +diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c +index 66bc74d..b35c857 100644 +--- a/drivers/video/backlight/adp8860_bl.c ++++ b/drivers/video/backlight/adp8860_bl.c +@@ -791,7 +791,7 @@ static int adp8860_i2c_suspend(struct i2c_client *client, pm_message_t message) + + static int adp8860_i2c_resume(struct i2c_client *client) + { +- adp8860_set_bits(client, ADP8860_MDCR, NSTBY); ++ adp8860_set_bits(client, ADP8860_MDCR, NSTBY | BLEN); + + return 0; + } +diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c +index 6c68a68..25a9b3a 100644 +--- a/drivers/video/backlight/adp8870_bl.c ++++ b/drivers/video/backlight/adp8870_bl.c +@@ -965,7 +965,7 @@ static int adp8870_i2c_suspend(struct i2c_client *client, pm_message_t message) + + static int adp8870_i2c_resume(struct i2c_client *client) + { +- adp8870_set_bits(client, ADP8870_MDCR, NSTBY); ++ adp8870_set_bits(client, ADP8870_MDCR, NSTBY | BLEN); + + return 0; + } +diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c +index bf9a9b7..9b8bcab 100644 +--- a/drivers/video/console/fbcon.c ++++ b/drivers/video/console/fbcon.c +@@ -530,6 +530,33 @@ static int search_for_mapped_con(void) + return retval; + } + ++static int do_fbcon_takeover(int show_logo) ++{ ++ int err, i; ++ ++ if (!num_registered_fb) ++ return -ENODEV; ++ ++ if (!show_logo) ++ logo_shown = FBCON_LOGO_DONTSHOW; ++ ++ for (i = first_fb_vc; i <= last_fb_vc; i++) ++ con2fb_map[i] = info_idx; ++ ++ err = do_take_over_console(&fb_con, first_fb_vc, last_fb_vc, ++ fbcon_is_default); ++ ++ if (err) { ++ for (i = first_fb_vc; i <= last_fb_vc; i++) ++ con2fb_map[i] = -1; ++ info_idx = -1; ++ } else { ++ fbcon_has_console_bind = 1; ++ } ++ ++ return err; ++} ++ + static int fbcon_takeover(int show_logo) + { + int err, i; +@@ -991,7 +1018,7 @@ static const char *fbcon_startup(void) + } + + /* Setup default font */ +- if (!p->fontdata) { ++ if (!p->fontdata && !vc->vc_font.data) { + if (!fontname[0] || !(font = find_font(fontname))) + font = get_default_font(info->var.xres, + info->var.yres, +@@ -1001,6 +1028,8 @@ static const char *fbcon_startup(void) + vc->vc_font.height = font->height; + vc->vc_font.data = (void *)(p->fontdata = font->data); + vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */ ++ } else { ++ p->fontdata = vc->vc_font.data; + } + + cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); +@@ -1160,9 +1189,9 @@ static void fbcon_init(struct vc_data *vc, int init) + ops->p = &fb_display[fg_console]; + } + +-static void fbcon_free_font(struct display *p) ++static void fbcon_free_font(struct display *p, bool freefont) + { +- if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) ++ if (freefont && p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) + kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int)); + p->fontdata = NULL; + p->userfont = 0; +@@ -1174,8 +1203,8 @@ static void fbcon_deinit(struct vc_data *vc) + struct fb_info *info; + struct fbcon_ops *ops; + int idx; ++ bool free_font = true; + +- fbcon_free_font(p); + idx = con2fb_map[vc->vc_num]; + + if (idx == -1) +@@ -1186,6 +1215,8 @@ static void fbcon_deinit(struct vc_data *vc) + if (!info) + goto finished; + ++ if (info->flags & FBINFO_MISC_FIRMWARE) ++ free_font = false; + ops = info->fbcon_par; + + if (!ops) +@@ -1197,6 +1228,8 @@ static void fbcon_deinit(struct vc_data *vc) + ops->flags &= ~FBCON_FLAGS_INIT; + finished: + ++ fbcon_free_font(p, free_font); ++ + if (!con_is_bound(&fb_con)) + fbcon_exit(); + +@@ -2978,7 +3011,7 @@ static int fbcon_unbind(void) + { + int ret; + +- ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc, ++ ret = do_unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc, + fbcon_is_default); + + if (!ret) +@@ -3051,7 +3084,7 @@ static int fbcon_fb_unregistered(struct fb_info *info) + primary_device = -1; + + if (!num_registered_fb) +- unregister_con_driver(&fb_con); ++ do_unregister_con_driver(&fb_con); + + return 0; + } +@@ -3116,7 +3149,7 @@ static int fbcon_fb_registered(struct fb_info *info) + } + + if (info_idx != -1) +- ret = fbcon_takeover(1); ++ ret = do_fbcon_takeover(1); + } else { + for (i = first_fb_vc; i <= last_fb_vc; i++) { + if (con2fb_map_boot[i] == idx) +diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c +index d449a74..5855d17 100644 +--- a/drivers/video/console/vgacon.c ++++ b/drivers/video/console/vgacon.c +@@ -1064,7 +1064,7 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512) + unsigned short video_port_status = vga_video_port_reg + 6; + int font_select = 0x00, beg, i; + char *charmap; +- ++ bool clear_attribs = false; + if (vga_video_type != VIDEO_TYPE_EGAM) { + charmap = (char *) VGA_MAP_MEM(colourmap, 0); + beg = 0x0e; +@@ -1169,12 +1169,6 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512) + + /* if 512 char mode is already enabled don't re-enable it. */ + if ((set) && (ch512 != vga_512_chars)) { +- /* attribute controller */ +- for (i = 0; i < MAX_NR_CONSOLES; i++) { +- struct vc_data *c = vc_cons[i].d; +- if (c && c->vc_sw == &vga_con) +- c->vc_hi_font_mask = ch512 ? 0x0800 : 0; +- } + vga_512_chars = ch512; + /* 256-char: enable intensity bit + 512-char: disable intensity bit */ +@@ -1185,8 +1179,22 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512) + it means, but it works, and it appears necessary */ + inb_p(video_port_status); + vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0); ++ clear_attribs = true; + } + raw_spin_unlock_irq(&vga_lock); ++ ++ if (clear_attribs) { ++ for (i = 0; i < MAX_NR_CONSOLES; i++) { ++ struct vc_data *c = vc_cons[i].d; ++ if (c && c->vc_sw == &vga_con) { ++ /* force hi font mask to 0, so we always clear ++ the bit on either transition */ ++ c->vc_hi_font_mask = 0x00; ++ clear_buffer_attributes(c); ++ c->vc_hi_font_mask = ch512 ? 0x0800 : 0; ++ } ++ } ++ } + return 0; + } + +diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c +index 7a41220..c133dde 100644 +--- a/drivers/video/fbmem.c ++++ b/drivers/video/fbmem.c +@@ -1628,7 +1628,9 @@ static int do_register_framebuffer(struct fb_info *fb_info) + event.info = fb_info; + if (!lock_fb_info(fb_info)) + return -ENODEV; ++ console_lock(); + fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event); ++ console_unlock(); + unlock_fb_info(fb_info); + return 0; + } +@@ -1644,8 +1646,10 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) + + if (!lock_fb_info(fb_info)) + return -ENODEV; ++ console_lock(); + event.info = fb_info; + ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event); ++ console_unlock(); + unlock_fb_info(fb_info); + + if (ret) +@@ -1660,7 +1664,9 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) + num_registered_fb--; + fb_cleanup_device(fb_info); + event.info = fb_info; ++ console_lock(); + fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); ++ console_unlock(); + + /* this may free fb info */ + put_fb_info(fb_info); +@@ -1831,11 +1837,8 @@ int fb_new_modelist(struct fb_info *info) + err = 1; + + if (!list_empty(&info->modelist)) { +- if (!lock_fb_info(info)) +- return -ENODEV; + event.info = info; + err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event); +- unlock_fb_info(info); + } + + return err; +diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c +index 67afa9c..303fb9f 100644 +--- a/drivers/video/fbsysfs.c ++++ b/drivers/video/fbsysfs.c +@@ -175,6 +175,8 @@ static ssize_t store_modes(struct device *device, + if (i * sizeof(struct fb_videomode) != count) + return -EINVAL; + ++ if (!lock_fb_info(fb_info)) ++ return -ENODEV; + console_lock(); + list_splice(&fb_info->modelist, &old_list); + fb_videomode_to_modelist((const struct fb_videomode *)buf, i, +@@ -186,6 +188,7 @@ static ssize_t store_modes(struct device *device, + fb_destroy_modelist(&old_list); + + console_unlock(); ++ unlock_fb_info(fb_info); + + return 0; + } +diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c +index dbc13e9..c93d59e 100644 +--- a/drivers/xen/evtchn.c ++++ b/drivers/xen/evtchn.c +@@ -269,6 +269,14 @@ static int evtchn_bind_to_user(struct per_user_data *u, int port) + u->name, (void *)(unsigned long)port); + if (rc >= 0) + rc = 0; ++ else { ++ /* bind failed, should close the port now */ ++ struct evtchn_close close; ++ close.port = port; ++ if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0) ++ BUG(); ++ set_port_user(port, NULL); ++ } + + return rc; + } +@@ -277,6 +285,8 @@ static void evtchn_unbind_from_user(struct per_user_data *u, int port) + { + int irq = irq_from_evtchn(port); + ++ BUG_ON(irq < 0); ++ + unbind_from_irqhandler(irq, (void *)(unsigned long)port); + + set_port_user(port, NULL); +diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c +index 63616d7..d07c4cd 100644 +--- a/drivers/xen/xen-pciback/pciback_ops.c ++++ b/drivers/xen/xen-pciback/pciback_ops.c +@@ -8,6 +8,7 @@ + #include <linux/bitops.h> + #include <xen/events.h> + #include <linux/sched.h> ++#include <linux/ratelimit.h> + #include "pciback.h" + + int verbose_request; +@@ -135,7 +136,6 @@ int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev, + struct pci_dev *dev, struct xen_pci_op *op) + { + struct xen_pcibk_dev_data *dev_data; +- int otherend = pdev->xdev->otherend_id; + int status; + + if (unlikely(verbose_request)) +@@ -144,8 +144,9 @@ int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev, + status = pci_enable_msi(dev); + + if (status) { +- printk(KERN_ERR "error enable msi for guest %x status %x\n", +- otherend, status); ++ pr_warn_ratelimited(DRV_NAME ": %s: error enabling MSI for guest %u: err %d\n", ++ pci_name(dev), pdev->xdev->otherend_id, ++ status); + op->value = 0; + return XEN_PCI_ERR_op_failed; + } +@@ -223,10 +224,10 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev, + pci_name(dev), i, + op->msix_entries[i].vector); + } +- } else { +- printk(KERN_WARNING DRV_NAME ": %s: failed to enable MSI-X: err %d!\n", +- pci_name(dev), result); +- } ++ } else ++ pr_warn_ratelimited(DRV_NAME ": %s: error enabling MSI-X for guest %u: err %d!\n", ++ pci_name(dev), pdev->xdev->otherend_id, ++ result); + kfree(entries); + + op->value = result; +diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c +index b8e8b0a..4a1b984 100644 +--- a/fs/binfmt_em86.c ++++ b/fs/binfmt_em86.c +@@ -42,7 +42,6 @@ static int load_em86(struct linux_binprm *bprm,struct pt_regs *regs) + return -ENOEXEC; + } + +- bprm->recursion_depth++; /* Well, the bang-shell is implicit... */ + allow_write_access(bprm->file); + fput(bprm->file); + bprm->file = NULL; +diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c +index ca52e92..7423cb9 100644 +--- a/fs/binfmt_misc.c ++++ b/fs/binfmt_misc.c +@@ -116,10 +116,6 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs) + if (!enabled) + goto _ret; + +- retval = -ENOEXEC; +- if (bprm->recursion_depth > BINPRM_MAX_RECURSION) +- goto _ret; +- + /* to keep locking time low, we copy the interpreter string */ + read_lock(&entries_lock); + fmt = check_file(bprm); +@@ -199,8 +195,6 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs) + if (retval < 0) + goto _error; + +- bprm->recursion_depth++; +- + retval = search_binary_handler (bprm, regs); + if (retval < 0) + goto _error; +diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c +index e39c18a..211ede0 100644 +--- a/fs/binfmt_script.c ++++ b/fs/binfmt_script.c +@@ -22,15 +22,13 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs) + char interp[BINPRM_BUF_SIZE]; + int retval; + +- if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || +- (bprm->recursion_depth > BINPRM_MAX_RECURSION)) ++ if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!')) + return -ENOEXEC; + /* + * This section does the #! interpretation. + * Sorta complicated, but hopefully it will work. -TYT + */ + +- bprm->recursion_depth++; + allow_write_access(bprm->file); + fput(bprm->file); + bprm->file = NULL; +diff --git a/fs/block_dev.c b/fs/block_dev.c +index 9b98987..613edd8 100644 +--- a/fs/block_dev.c ++++ b/fs/block_dev.c +@@ -82,13 +82,14 @@ sector_t blkdev_max_block(struct block_device *bdev) + } + + /* Kill _all_ buffers and pagecache , dirty or not.. */ +-static void kill_bdev(struct block_device *bdev) ++void kill_bdev(struct block_device *bdev) + { + if (bdev->bd_inode->i_mapping->nrpages == 0) + return; + invalidate_bh_lrus(); + truncate_inode_pages(bdev->bd_inode->i_mapping, 0); + } ++EXPORT_SYMBOL(kill_bdev); + + int set_blocksize(struct block_device *bdev, int size) + { +@@ -1024,6 +1025,7 @@ int revalidate_disk(struct gendisk *disk) + + mutex_lock(&bdev->bd_mutex); + check_disk_size_change(disk, bdev); ++ bdev->bd_invalidated = 0; + mutex_unlock(&bdev->bd_mutex); + bdput(bdev); + return ret; +diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c +index 0e3c092..b4d2438 100644 +--- a/fs/cachefiles/rdwr.c ++++ b/fs/cachefiles/rdwr.c +@@ -918,7 +918,7 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page) + * own time */ + dget(object->backer); + mntget(cache->mnt); +- file = dentry_open(object->backer, cache->mnt, O_RDWR, ++ file = dentry_open(object->backer, cache->mnt, O_RDWR | O_LARGEFILE, + cache->cache_cred); + if (IS_ERR(file)) { + ret = PTR_ERR(file); +diff --git a/fs/direct-io.c b/fs/direct-io.c +index d740ab6..ac401d2 100644 +--- a/fs/direct-io.c ++++ b/fs/direct-io.c +@@ -304,9 +304,9 @@ static ssize_t dio_complete(struct dio *dio, loff_t offset, ssize_t ret, bool is + dio->end_io(dio->iocb, offset, transferred, + dio->private, ret, is_async); + } else { ++ inode_dio_done(dio->inode); + if (is_async) + aio_complete(dio->iocb, ret, 0); +- inode_dio_done(dio->inode); + } + + return ret; +diff --git a/fs/exec.c b/fs/exec.c +index c27fa0d..312e297 100644 +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -1385,6 +1385,10 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) + struct linux_binfmt *fmt; + pid_t old_pid; + ++ /* This allows 4 levels of binfmt rewrites before failing hard. */ ++ if (depth > 5) ++ return -ELOOP; ++ + retval = security_bprm_check(bprm); + if (retval) + return retval; +@@ -1408,12 +1412,8 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) + if (!try_module_get(fmt->module)) + continue; + read_unlock(&binfmt_lock); ++ bprm->recursion_depth = depth + 1; + retval = fn(bprm, regs); +- /* +- * Restore the depth counter to its starting value +- * in this call, so we don't have to rely on every +- * load_binary function to restore it on return. +- */ + bprm->recursion_depth = depth; + if (retval >= 0) { + if (depth == 0) +diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c +index d6970f7..484ffee 100644 +--- a/fs/ext4/balloc.c ++++ b/fs/ext4/balloc.c +@@ -420,11 +420,16 @@ static int ext4_has_free_clusters(struct ext4_sb_info *sbi, + + free_clusters = percpu_counter_read_positive(fcc); + dirty_clusters = percpu_counter_read_positive(dcc); +- root_clusters = EXT4_B2C(sbi, ext4_r_blocks_count(sbi->s_es)); ++ ++ /* ++ * r_blocks_count should always be multiple of the cluster ratio so ++ * we are safe to do a plane bit shift only. ++ */ ++ root_clusters = ext4_r_blocks_count(sbi->s_es) >> sbi->s_cluster_bits; + + if (free_clusters - (nclusters + root_clusters + dirty_clusters) < + EXT4_FREECLUSTERS_WATERMARK) { +- free_clusters = EXT4_C2B(sbi, percpu_counter_sum_positive(fcc)); ++ free_clusters = percpu_counter_sum_positive(fcc); + dirty_clusters = percpu_counter_sum_positive(dcc); + } + /* Check whether we have space after accounting for current +diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c +index fbb92e6..b48e0dc 100644 +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -45,6 +45,17 @@ + + #include <trace/events/ext4.h> + ++/* ++ * used by extent splitting. ++ */ ++#define EXT4_EXT_MAY_ZEROOUT 0x1 /* safe to zeroout if split fails \ ++ due to ENOSPC */ ++#define EXT4_EXT_MARK_UNINIT1 0x2 /* mark first half uninitialized */ ++#define EXT4_EXT_MARK_UNINIT2 0x4 /* mark second half uninitialized */ ++ ++#define EXT4_EXT_DATA_VALID1 0x8 /* first half contains valid data */ ++#define EXT4_EXT_DATA_VALID2 0x10 /* second half contains valid data */ ++ + static int ext4_split_extent(handle_t *handle, + struct inode *inode, + struct ext4_ext_path *path, +@@ -52,6 +63,13 @@ static int ext4_split_extent(handle_t *handle, + int split_flag, + int flags); + ++static int ext4_split_extent_at(handle_t *handle, ++ struct inode *inode, ++ struct ext4_ext_path *path, ++ ext4_lblk_t split, ++ int split_flag, ++ int flags); ++ + static int ext4_ext_truncate_extend_restart(handle_t *handle, + struct inode *inode, + int needed) +@@ -636,6 +654,7 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, + struct ext4_extent_header *eh; + struct buffer_head *bh; + short int depth, i, ppos = 0, alloc = 0; ++ int ret; + + eh = ext_inode_hdr(inode); + depth = ext_depth(inode); +@@ -665,12 +684,15 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, + path[ppos].p_ext = NULL; + + bh = sb_getblk(inode->i_sb, path[ppos].p_block); +- if (unlikely(!bh)) ++ if (unlikely(!bh)) { ++ ret = -ENOMEM; + goto err; ++ } + if (!bh_uptodate_or_lock(bh)) { + trace_ext4_ext_load_extent(inode, block, + path[ppos].p_block); +- if (bh_submit_read(bh) < 0) { ++ ret = bh_submit_read(bh); ++ if (ret < 0) { + put_bh(bh); + goto err; + } +@@ -683,13 +705,15 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block, + put_bh(bh); + EXT4_ERROR_INODE(inode, + "ppos %d > depth %d", ppos, depth); ++ ret = -EIO; + goto err; + } + path[ppos].p_bh = bh; + path[ppos].p_hdr = eh; + i--; + +- if (need_to_validate && ext4_ext_check(inode, eh, i)) ++ ret = need_to_validate ? ext4_ext_check(inode, eh, i) : 0; ++ if (ret < 0) + goto err; + } + +@@ -711,7 +735,7 @@ err: + ext4_ext_drop_refs(path); + if (alloc) + kfree(path); +- return ERR_PTR(-EIO); ++ return ERR_PTR(ret); + } + + /* +@@ -866,7 +890,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, + } + bh = sb_getblk(inode->i_sb, newblock); + if (!bh) { +- err = -EIO; ++ err = -ENOMEM; + goto cleanup; + } + lock_buffer(bh); +@@ -938,7 +962,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, + newblock = ablocks[--a]; + bh = sb_getblk(inode->i_sb, newblock); + if (!bh) { +- err = -EIO; ++ err = -ENOMEM; + goto cleanup; + } + lock_buffer(bh); +@@ -1049,11 +1073,8 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, + return err; + + bh = sb_getblk(inode->i_sb, newblock); +- if (!bh) { +- err = -EIO; +- ext4_std_error(inode->i_sb, err); +- return err; +- } ++ if (!bh) ++ return -ENOMEM; + lock_buffer(bh); + + err = ext4_journal_get_create_access(handle, bh); +@@ -2321,7 +2342,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, + struct ext4_extent *ex; + + /* the header must be checked already in ext4_ext_remove_space() */ +- ext_debug("truncate since %u in leaf\n", start); ++ ext_debug("truncate since %u in leaf to %u\n", start, end); + if (!path[depth].p_hdr) + path[depth].p_hdr = ext_block_hdr(path[depth].p_bh); + eh = path[depth].p_hdr; +@@ -2356,7 +2377,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, + ext_debug(" border %u:%u\n", a, b); + + /* If this extent is beyond the end of the hole, skip it */ +- if (end <= ex_ee_block) { ++ if (end < ex_ee_block) { + ex--; + ex_ee_block = le32_to_cpu(ex->ee_block); + ex_ee_len = ext4_ext_get_actual_len(ex); +@@ -2495,16 +2516,17 @@ ext4_ext_more_to_rm(struct ext4_ext_path *path) + return 1; + } + +-static int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start) ++static int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start, ++ ext4_lblk_t end) + { + struct super_block *sb = inode->i_sb; + int depth = ext_depth(inode); +- struct ext4_ext_path *path; ++ struct ext4_ext_path *path = NULL; + ext4_fsblk_t partial_cluster = 0; + handle_t *handle; +- int i, err; ++ int i = 0, err; + +- ext_debug("truncate since %u\n", start); ++ ext_debug("truncate since %u to %u\n", start, end); + + /* probably first extent we're gonna free will be last in block */ + handle = ext4_journal_start(inode, depth + 1); +@@ -2517,29 +2539,96 @@ again: + trace_ext4_ext_remove_space(inode, start, depth); + + /* ++ * Check if we are removing extents inside the extent tree. If that ++ * is the case, we are going to punch a hole inside the extent tree ++ * so we have to check whether we need to split the extent covering ++ * the last block to remove so we can easily remove the part of it ++ * in ext4_ext_rm_leaf(). ++ */ ++ if (end < EXT_MAX_BLOCKS - 1) { ++ struct ext4_extent *ex; ++ ext4_lblk_t ee_block; ++ ++ /* find extent for this block */ ++ path = ext4_ext_find_extent(inode, end, NULL); ++ if (IS_ERR(path)) { ++ ext4_journal_stop(handle); ++ return PTR_ERR(path); ++ } ++ depth = ext_depth(inode); ++ ex = path[depth].p_ext; ++ if (!ex) { ++ ext4_ext_drop_refs(path); ++ kfree(path); ++ path = NULL; ++ goto cont; ++ } ++ ++ ee_block = le32_to_cpu(ex->ee_block); ++ ++ /* ++ * See if the last block is inside the extent, if so split ++ * the extent at 'end' block so we can easily remove the ++ * tail of the first part of the split extent in ++ * ext4_ext_rm_leaf(). ++ */ ++ if (end >= ee_block && ++ end < ee_block + ext4_ext_get_actual_len(ex) - 1) { ++ int split_flag = 0; ++ ++ if (ext4_ext_is_uninitialized(ex)) ++ split_flag = EXT4_EXT_MARK_UNINIT1 | ++ EXT4_EXT_MARK_UNINIT2; ++ ++ /* ++ * Split the extent in two so that 'end' is the last ++ * block in the first new extent ++ */ ++ err = ext4_split_extent_at(handle, inode, path, ++ end + 1, split_flag, ++ EXT4_GET_BLOCKS_PRE_IO | ++ EXT4_GET_BLOCKS_PUNCH_OUT_EXT); ++ ++ if (err < 0) ++ goto out; ++ } ++ } ++cont: ++ ++ /* + * We start scanning from right side, freeing all the blocks + * after i_size and walking into the tree depth-wise. + */ + depth = ext_depth(inode); +- path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1), GFP_NOFS); +- if (path == NULL) { +- ext4_journal_stop(handle); +- return -ENOMEM; +- } +- path[0].p_depth = depth; +- path[0].p_hdr = ext_inode_hdr(inode); +- if (ext4_ext_check(inode, path[0].p_hdr, depth)) { +- err = -EIO; +- goto out; ++ if (path) { ++ int k = i = depth; ++ while (--k > 0) ++ path[k].p_block = ++ le16_to_cpu(path[k].p_hdr->eh_entries)+1; ++ } else { ++ path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1), ++ GFP_NOFS); ++ if (path == NULL) { ++ ext4_journal_stop(handle); ++ return -ENOMEM; ++ } ++ path[0].p_depth = depth; ++ path[0].p_hdr = ext_inode_hdr(inode); ++ i = 0; ++ ++ if (ext4_ext_check(inode, path[0].p_hdr, depth)) { ++ err = -EIO; ++ goto out; ++ } + } +- i = err = 0; ++ err = 0; + + while (i >= 0 && err == 0) { + if (i == depth) { + /* this is leaf block */ + err = ext4_ext_rm_leaf(handle, inode, path, + &partial_cluster, start, +- EXT_MAX_BLOCKS - 1); ++ end); + /* root level has p_bh == NULL, brelse() eats this */ + brelse(path[i].p_bh); + path[i].p_bh = NULL; +@@ -2646,8 +2735,10 @@ again: + out: + ext4_ext_drop_refs(path); + kfree(path); +- if (err == -EAGAIN) ++ if (err == -EAGAIN) { ++ path = NULL; + goto again; ++ } + ext4_journal_stop(handle); + + return err; +@@ -2722,17 +2813,6 @@ static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex) + } + + /* +- * used by extent splitting. +- */ +-#define EXT4_EXT_MAY_ZEROOUT 0x1 /* safe to zeroout if split fails \ +- due to ENOSPC */ +-#define EXT4_EXT_MARK_UNINIT1 0x2 /* mark first half uninitialized */ +-#define EXT4_EXT_MARK_UNINIT2 0x4 /* mark second half uninitialized */ +- +-#define EXT4_EXT_DATA_VALID1 0x8 /* first half contains valid data */ +-#define EXT4_EXT_DATA_VALID2 0x10 /* second half contains valid data */ +- +-/* + * ext4_split_extent_at() splits an extent at given block. + * + * @handle: the journal handle +@@ -4274,7 +4354,7 @@ void ext4_ext_truncate(struct inode *inode) + + last_block = (inode->i_size + sb->s_blocksize - 1) + >> EXT4_BLOCK_SIZE_BITS(sb); +- err = ext4_ext_remove_space(inode, last_block); ++ err = ext4_ext_remove_space(inode, last_block, EXT_MAX_BLOCKS - 1); + + /* In a multi-transaction truncate, we only make the final + * transaction synchronous. +@@ -4751,14 +4831,12 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length) + { + struct inode *inode = file->f_path.dentry->d_inode; + struct super_block *sb = inode->i_sb; +- struct ext4_ext_cache cache_ex; +- ext4_lblk_t first_block, last_block, num_blocks, iblock, max_blocks; ++ ext4_lblk_t first_block, stop_block; + struct address_space *mapping = inode->i_mapping; +- struct ext4_map_blocks map; + handle_t *handle; + loff_t first_page, last_page, page_len; + loff_t first_page_offset, last_page_offset; +- int ret, credits, blocks_released, err = 0; ++ int credits, err = 0; + + /* No need to punch hole beyond i_size */ + if (offset >= inode->i_size) +@@ -4774,10 +4852,6 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length) + offset; + } + +- first_block = (offset + sb->s_blocksize - 1) >> +- EXT4_BLOCK_SIZE_BITS(sb); +- last_block = (offset + length) >> EXT4_BLOCK_SIZE_BITS(sb); +- + first_page = (offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; + last_page = (offset + length) >> PAGE_CACHE_SHIFT; + +@@ -4856,7 +4930,6 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length) + } + } + +- + /* + * If i_size is contained in the last page, we need to + * unmap and zero the partial page after i_size +@@ -4876,73 +4949,22 @@ int ext4_ext_punch_hole(struct file *file, loff_t offset, loff_t length) + } + } + ++ first_block = (offset + sb->s_blocksize - 1) >> ++ EXT4_BLOCK_SIZE_BITS(sb); ++ stop_block = (offset + length) >> EXT4_BLOCK_SIZE_BITS(sb); ++ + /* If there are no blocks to remove, return now */ +- if (first_block >= last_block) ++ if (first_block >= stop_block) + goto out; + + down_write(&EXT4_I(inode)->i_data_sem); + ext4_ext_invalidate_cache(inode); + ext4_discard_preallocations(inode); + +- /* +- * Loop over all the blocks and identify blocks +- * that need to be punched out +- */ +- iblock = first_block; +- blocks_released = 0; +- while (iblock < last_block) { +- max_blocks = last_block - iblock; +- num_blocks = 1; +- memset(&map, 0, sizeof(map)); +- map.m_lblk = iblock; +- map.m_len = max_blocks; +- ret = ext4_ext_map_blocks(handle, inode, &map, +- EXT4_GET_BLOCKS_PUNCH_OUT_EXT); +- +- if (ret > 0) { +- blocks_released += ret; +- num_blocks = ret; +- } else if (ret == 0) { +- /* +- * If map blocks could not find the block, +- * then it is in a hole. If the hole was +- * not already cached, then map blocks should +- * put it in the cache. So we can get the hole +- * out of the cache +- */ +- memset(&cache_ex, 0, sizeof(cache_ex)); +- if ((ext4_ext_check_cache(inode, iblock, &cache_ex)) && +- !cache_ex.ec_start) { +- +- /* The hole is cached */ +- num_blocks = cache_ex.ec_block + +- cache_ex.ec_len - iblock; ++ err = ext4_ext_remove_space(inode, first_block, stop_block - 1); + +- } else { +- /* The block could not be identified */ +- err = -EIO; +- break; +- } +- } else { +- /* Map blocks error */ +- err = ret; +- break; +- } +- +- if (num_blocks == 0) { +- /* This condition should never happen */ +- ext_debug("Block lookup failed"); +- err = -EIO; +- break; +- } +- +- iblock += num_blocks; +- } +- +- if (blocks_released > 0) { +- ext4_ext_invalidate_cache(inode); +- ext4_discard_preallocations(inode); +- } ++ ext4_ext_invalidate_cache(inode); ++ ext4_discard_preallocations(inode); + + if (IS_SYNC(inode)) + ext4_handle_sync(handle); +diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c +index 3cfc73f..26d6dbf 100644 +--- a/fs/ext4/indirect.c ++++ b/fs/ext4/indirect.c +@@ -146,6 +146,7 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth, + struct super_block *sb = inode->i_sb; + Indirect *p = chain; + struct buffer_head *bh; ++ int ret = -EIO; + + *err = 0; + /* i_data is not going away, no lock needed */ +@@ -154,8 +155,10 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth, + goto no_block; + while (--depth) { + bh = sb_getblk(sb, le32_to_cpu(p->key)); +- if (unlikely(!bh)) ++ if (unlikely(!bh)) { ++ ret = -ENOMEM; + goto failure; ++ } + + if (!bh_uptodate_or_lock(bh)) { + if (bh_submit_read(bh) < 0) { +@@ -177,7 +180,7 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth, + return NULL; + + failure: +- *err = -EIO; ++ *err = ret; + no_block: + return p; + } +@@ -471,7 +474,7 @@ static int ext4_alloc_branch(handle_t *handle, struct inode *inode, + */ + bh = sb_getblk(inode->i_sb, new_blocks[n-1]); + if (unlikely(!bh)) { +- err = -EIO; ++ err = -ENOMEM; + goto failed; + } + +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index 8424dda..4b2bb75 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -661,7 +661,7 @@ struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode, + + bh = sb_getblk(inode->i_sb, map.m_pblk); + if (!bh) { +- *errp = -EIO; ++ *errp = -ENOMEM; + return NULL; + } + if (map.m_flags & EXT4_MAP_NEW) { +@@ -2795,9 +2795,9 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset, + if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) { + ext4_free_io_end(io_end); + out: ++ inode_dio_done(inode); + if (is_async) + aio_complete(iocb, ret, 0); +- inode_dio_done(inode); + return; + } + +@@ -3575,11 +3575,8 @@ static int __ext4_get_inode_loc(struct inode *inode, + iloc->offset = (inode_offset % inodes_per_block) * EXT4_INODE_SIZE(sb); + + bh = sb_getblk(sb, block); +- if (!bh) { +- EXT4_ERROR_INODE_BLOCK(inode, block, +- "unable to read itable block"); +- return -EIO; +- } ++ if (!bh) ++ return -ENOMEM; + if (!buffer_uptodate(bh)) { + lock_buffer(bh); + +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 1d07c12..553ff71 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -4178,7 +4178,7 @@ static void ext4_mb_add_n_trim(struct ext4_allocation_context *ac) + /* The max size of hash table is PREALLOC_TB_SIZE */ + order = PREALLOC_TB_SIZE - 1; + /* Add the prealloc space to lg */ +- rcu_read_lock(); ++ spin_lock(&lg->lg_prealloc_lock); + list_for_each_entry_rcu(tmp_pa, &lg->lg_prealloc_list[order], + pa_inode_list) { + spin_lock(&tmp_pa->pa_lock); +@@ -4202,12 +4202,12 @@ static void ext4_mb_add_n_trim(struct ext4_allocation_context *ac) + if (!added) + list_add_tail_rcu(&pa->pa_inode_list, + &lg->lg_prealloc_list[order]); +- rcu_read_unlock(); ++ spin_unlock(&lg->lg_prealloc_lock); + + /* Now trim the list to be not more than 8 elements */ + if (lg_prealloc_count > 8) { + ext4_mb_discard_lg_preallocations(sb, lg, +- order, lg_prealloc_count); ++ order, lg_prealloc_count); + return; + } + return ; +diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c +index 7ea4ba4..f3358ab 100644 +--- a/fs/ext4/mmp.c ++++ b/fs/ext4/mmp.c +@@ -41,6 +41,8 @@ static int read_mmp_block(struct super_block *sb, struct buffer_head **bh, + * is not blocked in the elevator. */ + if (!*bh) + *bh = sb_getblk(sb, mmp_block); ++ if (!*bh) ++ return -ENOMEM; + if (*bh) { + get_bh(*bh); + lock_buffer(*bh); +diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c +index 24feb1c..54f566d 100644 +--- a/fs/ext4/page-io.c ++++ b/fs/ext4/page-io.c +@@ -108,14 +108,13 @@ int ext4_end_io_nolock(ext4_io_end_t *io) + inode->i_ino, offset, size, ret); + } + +- if (io->iocb) +- aio_complete(io->iocb, io->result, 0); +- +- if (io->flag & EXT4_IO_END_DIRECT) +- inode_dio_done(inode); + /* Wake up anyone waiting on unwritten extent conversion */ + if (atomic_dec_and_test(&EXT4_I(inode)->i_aiodio_unwritten)) + wake_up_all(ext4_ioend_wq(io->inode)); ++ if (io->flag & EXT4_IO_END_DIRECT) ++ inode_dio_done(inode); ++ if (io->iocb) ++ aio_complete(io->iocb, io->result, 0); + return ret; + } + +diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c +index 4eac337..33129c0 100644 +--- a/fs/ext4/resize.c ++++ b/fs/ext4/resize.c +@@ -142,7 +142,7 @@ static struct buffer_head *bclean(handle_t *handle, struct super_block *sb, + + bh = sb_getblk(sb, blk); + if (!bh) +- return ERR_PTR(-EIO); ++ return ERR_PTR(-ENOMEM); + if ((err = ext4_journal_get_write_access(handle, bh))) { + brelse(bh); + bh = ERR_PTR(err); +@@ -220,7 +220,7 @@ static int setup_new_group_blocks(struct super_block *sb, + + gdb = sb_getblk(sb, block); + if (!gdb) { +- err = -EIO; ++ err = -ENOMEM; + goto exit_journal; + } + if ((err = ext4_journal_get_write_access(handle, gdb))) { +@@ -694,7 +694,7 @@ static void update_backups(struct super_block *sb, + + bh = sb_getblk(sb, group * bpg + blk_off); + if (!bh) { +- err = -EIO; ++ err = -ENOMEM; + break; + } + ext4_debug("update metadata backup %#04lx\n", +diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c +index 4410ae7..d5498b2 100644 +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -496,7 +496,7 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode, + error = ext4_handle_dirty_metadata(handle, inode, bh); + if (IS_SYNC(inode)) + ext4_handle_sync(handle); +- dquot_free_block(inode, 1); ++ dquot_free_block(inode, EXT4_C2B(EXT4_SB(inode->i_sb), 1)); + ea_bdebug(bh, "refcount now=%d; releasing", + le32_to_cpu(BHDR(bh)->h_refcount)); + } +@@ -785,7 +785,8 @@ inserted: + else { + /* The old block is released after updating + the inode. */ +- error = dquot_alloc_block(inode, 1); ++ error = dquot_alloc_block(inode, ++ EXT4_C2B(EXT4_SB(sb), 1)); + if (error) + goto cleanup; + error = ext4_journal_get_write_access(handle, +@@ -839,16 +840,17 @@ inserted: + + new_bh = sb_getblk(sb, block); + if (!new_bh) { ++ error = -ENOMEM; + getblk_failed: + ext4_free_blocks(handle, inode, NULL, block, 1, + EXT4_FREE_BLOCKS_METADATA); +- error = -EIO; + goto cleanup; + } + lock_buffer(new_bh); + error = ext4_journal_get_create_access(handle, new_bh); + if (error) { + unlock_buffer(new_bh); ++ error = -EIO; + goto getblk_failed; + } + memcpy(new_bh->b_data, s->base, new_bh->b_size); +@@ -880,7 +882,7 @@ cleanup: + return error; + + cleanup_dquot: +- dquot_free_block(inode, 1); ++ dquot_free_block(inode, EXT4_C2B(EXT4_SB(sb), 1)); + goto cleanup; + + bad_block: +diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c +index 8392cb8..a3a0987 100644 +--- a/fs/lockd/clntproc.c ++++ b/fs/lockd/clntproc.c +@@ -551,6 +551,9 @@ again: + status = nlmclnt_block(block, req, NLMCLNT_POLL_TIMEOUT); + if (status < 0) + break; ++ /* Resend the blocking lock request after a server reboot */ ++ if (resp->status == nlm_lck_denied_grace_period) ++ continue; + if (resp->status != nlm_lck_blocked) + break; + } +diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c +index 1aaa0ee..b17a81c 100644 +--- a/fs/nfs/blocklayout/blocklayout.c ++++ b/fs/nfs/blocklayout/blocklayout.c +@@ -1101,6 +1101,7 @@ static const struct nfs_pageio_ops bl_pg_write_ops = { + static struct pnfs_layoutdriver_type blocklayout_type = { + .id = LAYOUT_BLOCK_VOLUME, + .name = "LAYOUT_BLOCK_VOLUME", ++ .owner = THIS_MODULE, + .read_pagelist = bl_read_pagelist, + .write_pagelist = bl_write_pagelist, + .alloc_layout_hdr = bl_alloc_layout_hdr, +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 2f98c53..6d7c53d 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -5891,7 +5891,8 @@ int nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags) + status = nfs4_wait_for_completion_rpc_task(task); + if (status == 0) + status = task->tk_status; +- if (status == 0) ++ /* if layoutp->len is 0, nfs4_layoutget_prepare called rpc_exit */ ++ if (status == 0 && lgp->res.layoutp->len) + status = pnfs_layout_process(lgp); + rpc_put_task(task); + dprintk("<-- %s status=%d\n", __func__, status); +diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c +index a03ee52..c1897f7 100644 +--- a/fs/nfs/objlayout/objio_osd.c ++++ b/fs/nfs/objlayout/objio_osd.c +@@ -569,6 +569,7 @@ static struct pnfs_layoutdriver_type objlayout_type = { + .flags = PNFS_LAYOUTRET_ON_SETATTR | + PNFS_LAYOUTRET_ON_ERROR, + ++ .owner = THIS_MODULE, + .alloc_layout_hdr = objlayout_alloc_layout_hdr, + .free_layout_hdr = objlayout_free_layout_hdr, + +diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c +index 8b197d2..7d189dc 100644 +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -1009,6 +1009,8 @@ free_client(struct nfs4_client *clp) + put_group_info(clp->cl_cred.cr_group_info); + kfree(clp->cl_principal); + kfree(clp->cl_name.data); ++ idr_remove_all(&clp->cl_stateids); ++ idr_destroy(&clp->cl_stateids); + kfree(clp); + } + +diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c +index 8445fbc..6f292dd 100644 +--- a/fs/notify/inotify/inotify_user.c ++++ b/fs/notify/inotify/inotify_user.c +@@ -579,8 +579,6 @@ static int inotify_update_existing_watch(struct fsnotify_group *group, + + /* don't allow invalid bits: we don't want flags set */ + mask = inotify_arg_to_mask(arg); +- if (unlikely(!(mask & IN_ALL_EVENTS))) +- return -EINVAL; + + fsn_mark = fsnotify_find_inode_mark(group, inode); + if (!fsn_mark) +@@ -632,8 +630,6 @@ static int inotify_new_watch(struct fsnotify_group *group, + + /* don't allow invalid bits: we don't want flags set */ + mask = inotify_arg_to_mask(arg); +- if (unlikely(!(mask & IN_ALL_EVENTS))) +- return -EINVAL; + + tmp_i_mark = kmem_cache_alloc(inotify_inode_mark_cachep, GFP_KERNEL); + if (unlikely(!tmp_i_mark)) +diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c +index 78b68af..4402b18 100644 +--- a/fs/ocfs2/aops.c ++++ b/fs/ocfs2/aops.c +@@ -593,9 +593,9 @@ static void ocfs2_dio_end_io(struct kiocb *iocb, + level = ocfs2_iocb_rw_locked_level(iocb); + ocfs2_rw_unlock(inode, level); + ++ inode_dio_done(inode); + if (is_async) + aio_complete(iocb, ret, 0); +- inode_dio_done(inode); + } + + /* +diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c +index 81a4cd2..231eab2 100644 +--- a/fs/ocfs2/dlmglue.c ++++ b/fs/ocfs2/dlmglue.c +@@ -2545,6 +2545,7 @@ int ocfs2_super_lock(struct ocfs2_super *osb, + * everything is up to the caller :) */ + status = ocfs2_should_refresh_lock_res(lockres); + if (status < 0) { ++ ocfs2_cluster_unlock(osb, lockres, level); + mlog_errno(status); + goto bail; + } +@@ -2553,8 +2554,10 @@ int ocfs2_super_lock(struct ocfs2_super *osb, + + ocfs2_complete_lock_res_refresh(lockres, status); + +- if (status < 0) ++ if (status < 0) { ++ ocfs2_cluster_unlock(osb, lockres, level); + mlog_errno(status); ++ } + ocfs2_track_lock_refresh(lockres); + } + bail: +diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c +index f169da4..b7e74b5 100644 +--- a/fs/ocfs2/suballoc.c ++++ b/fs/ocfs2/suballoc.c +@@ -642,7 +642,7 @@ ocfs2_block_group_alloc_discontig(handle_t *handle, + * cluster groups will be staying in cache for the duration of + * this operation. + */ +- ac->ac_allow_chain_relink = 0; ++ ac->ac_disable_chain_relink = 1; + + /* Claim the first region */ + status = ocfs2_block_group_claim_bits(osb, handle, ac, min_bits, +@@ -1823,7 +1823,7 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, + * Do this *after* figuring out how many bits we're taking out + * of our target group. + */ +- if (ac->ac_allow_chain_relink && ++ if (!ac->ac_disable_chain_relink && + (prev_group_bh) && + (ocfs2_block_group_reasonably_empty(bg, res->sr_bits))) { + status = ocfs2_relink_block_group(handle, alloc_inode, +@@ -1928,7 +1928,6 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, + + victim = ocfs2_find_victim_chain(cl); + ac->ac_chain = victim; +- ac->ac_allow_chain_relink = 1; + + status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits, + res, &bits_left); +@@ -1947,7 +1946,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, + * searching each chain in order. Don't allow chain relinking + * because we only calculate enough journal credits for one + * relink per alloc. */ +- ac->ac_allow_chain_relink = 0; ++ ac->ac_disable_chain_relink = 1; + for (i = 0; i < le16_to_cpu(cl->cl_next_free_rec); i ++) { + if (i == victim) + continue; +diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h +index b8afabf..a36d0aa 100644 +--- a/fs/ocfs2/suballoc.h ++++ b/fs/ocfs2/suballoc.h +@@ -49,7 +49,7 @@ struct ocfs2_alloc_context { + + /* these are used by the chain search */ + u16 ac_chain; +- int ac_allow_chain_relink; ++ int ac_disable_chain_relink; + group_search_t *ac_group_search; + + u64 ac_last_group; +diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c +index aa9e877..0d5ea9c 100644 +--- a/fs/ocfs2/xattr.c ++++ b/fs/ocfs2/xattr.c +@@ -7189,7 +7189,7 @@ int ocfs2_init_security_and_acl(struct inode *dir, + struct buffer_head *dir_bh = NULL; + + ret = ocfs2_init_security_get(inode, dir, qstr, NULL); +- if (!ret) { ++ if (ret) { + mlog_errno(ret); + goto leave; + } +diff --git a/fs/partitions/check.c b/fs/partitions/check.c +index 6b5fcc5..1ef15cc 100644 +--- a/fs/partitions/check.c ++++ b/fs/partitions/check.c +@@ -399,11 +399,11 @@ void delete_partition(struct gendisk *disk, int partno) + if (!part) + return; + +- blk_free_devt(part_devt(part)); + rcu_assign_pointer(ptbl->part[partno], NULL); + rcu_assign_pointer(ptbl->last_lookup, NULL); + kobject_put(part->holder_dir); + device_del(part_to_dev(part)); ++ blk_free_devt(part_devt(part)); + + hd_struct_put(part); + } +diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c +index 57bbf90..45d18d1 100644 +--- a/fs/pstore/platform.c ++++ b/fs/pstore/platform.c +@@ -72,6 +72,27 @@ static char *reason_str[] = { + "Oops", "Panic", "Kexec", "Restart", "Halt", "Poweroff", "Emergency" + }; + ++bool pstore_cannot_block_path(enum kmsg_dump_reason reason) ++{ ++ /* ++ * In case of NMI path, pstore shouldn't be blocked ++ * regardless of reason. ++ */ ++ if (in_nmi()) ++ return true; ++ ++ switch (reason) { ++ /* In panic case, other cpus are stopped by smp_send_stop(). */ ++ case KMSG_DUMP_PANIC: ++ /* Emergency restart shouldn't be blocked by spin lock. */ ++ case KMSG_DUMP_EMERG: ++ return true; ++ default: ++ return false; ++ } ++} ++EXPORT_SYMBOL_GPL(pstore_cannot_block_path); ++ + /* + * callback from kmsg_dump. (s2,l2) has the most recently + * written bytes, older bytes are in (s1,l1). Save as much +@@ -97,10 +118,12 @@ static void pstore_dump(struct kmsg_dumper *dumper, + else + why = "Unknown"; + +- if (in_nmi()) { +- is_locked = spin_trylock(&psinfo->buf_lock); +- if (!is_locked) +- pr_err("pstore dump routine blocked in NMI, may corrupt error record\n"); ++ if (pstore_cannot_block_path(reason)) { ++ is_locked = spin_trylock_irqsave(&psinfo->buf_lock, flags); ++ if (!is_locked) { ++ pr_err("pstore dump routine blocked in %s path, may corrupt error record\n" ++ , in_nmi() ? "NMI" : why); ++ } + } else + spin_lock_irqsave(&psinfo->buf_lock, flags); + oopscount++; +@@ -131,9 +154,9 @@ static void pstore_dump(struct kmsg_dumper *dumper, + total += l1_cpy + l2_cpy; + part++; + } +- if (in_nmi()) { ++ if (pstore_cannot_block_path(reason)) { + if (is_locked) +- spin_unlock(&psinfo->buf_lock); ++ spin_unlock_irqrestore(&psinfo->buf_lock, flags); + } else + spin_unlock_irqrestore(&psinfo->buf_lock, flags); + } +diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c +index c542c73..f9c90b5 100644 +--- a/fs/ubifs/orphan.c ++++ b/fs/ubifs/orphan.c +@@ -130,13 +130,14 @@ void ubifs_delete_orphan(struct ubifs_info *c, ino_t inum) + else if (inum > o->inum) + p = p->rb_right; + else { +- if (o->dnext) { ++ if (o->del) { + spin_unlock(&c->orphan_lock); + dbg_gen("deleted twice ino %lu", + (unsigned long)inum); + return; + } + if (o->cnext) { ++ o->del = 1; + o->dnext = c->orph_dnext; + c->orph_dnext = o; + spin_unlock(&c->orphan_lock); +@@ -447,6 +448,7 @@ static void erase_deleted(struct ubifs_info *c) + orphan = dnext; + dnext = orphan->dnext; + ubifs_assert(!orphan->new); ++ ubifs_assert(orphan->del); + rb_erase(&orphan->rb, &c->orph_tree); + list_del(&orphan->list); + c->tot_orphans -= 1; +@@ -536,6 +538,7 @@ static int insert_dead_orphan(struct ubifs_info *c, ino_t inum) + rb_link_node(&orphan->rb, parent, p); + rb_insert_color(&orphan->rb, &c->orph_tree); + list_add_tail(&orphan->list, &c->orph_list); ++ orphan->del = 1; + orphan->dnext = c->orph_dnext; + c->orph_dnext = orphan; + dbg_mnt("ino %lu, new %d, tot %d", (unsigned long)inum, +diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h +index 8bbc99e..a39fce5 100644 +--- a/fs/ubifs/ubifs.h ++++ b/fs/ubifs/ubifs.h +@@ -908,6 +908,7 @@ struct ubifs_budget_req { + * @dnext: next orphan to delete + * @inum: inode number + * @new: %1 => added since the last commit, otherwise %0 ++ * @del: %1 => delete pending, otherwise %0 + */ + struct ubifs_orphan { + struct rb_node rb; +@@ -917,6 +918,7 @@ struct ubifs_orphan { + struct ubifs_orphan *dnext; + ino_t inum; + int new; ++ unsigned del:1; + }; + + /** +diff --git a/include/linux/auto_fs.h b/include/linux/auto_fs.h +index da64e15..6cdabb4 100644 +--- a/include/linux/auto_fs.h ++++ b/include/linux/auto_fs.h +@@ -31,25 +31,16 @@ + #define AUTOFS_MIN_PROTO_VERSION AUTOFS_PROTO_VERSION + + /* +- * Architectures where both 32- and 64-bit binaries can be executed +- * on 64-bit kernels need this. This keeps the structure format +- * uniform, and makes sure the wait_queue_token isn't too big to be +- * passed back down to the kernel. +- * +- * This assumes that on these architectures: +- * mode 32 bit 64 bit +- * ------------------------- +- * int 32 bit 32 bit +- * long 32 bit 64 bit +- * +- * If so, 32-bit user-space code should be backwards compatible. ++ * The wait_queue_token (autofs_wqt_t) is part of a structure which is passed ++ * back to the kernel via ioctl from userspace. On architectures where 32- and ++ * 64-bit userspace binaries can be executed it's important that the size of ++ * autofs_wqt_t stays constant between 32- and 64-bit Linux kernels so that we ++ * do not break the binary ABI interface by changing the structure size. + */ +- +-#if defined(__sparc__) || defined(__mips__) || defined(__x86_64__) \ +- || defined(__powerpc__) || defined(__s390__) +-typedef unsigned int autofs_wqt_t; +-#else ++#if defined(__ia64__) || defined(__alpha__) /* pure 64bit architectures */ + typedef unsigned long autofs_wqt_t; ++#else ++typedef unsigned int autofs_wqt_t; + #endif + + /* Packet types */ +diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h +index f606406..acd8d4b 100644 +--- a/include/linux/binfmts.h ++++ b/include/linux/binfmts.h +@@ -67,8 +67,6 @@ struct linux_binprm { + #define BINPRM_FLAGS_EXECFD_BIT 1 + #define BINPRM_FLAGS_EXECFD (1 << BINPRM_FLAGS_EXECFD_BIT) + +-#define BINPRM_MAX_RECURSION 4 +- + /* Function parameter for binfmt->coredump */ + struct coredump_params { + long signr; +diff --git a/include/linux/console.h b/include/linux/console.h +index 7453cfd..6ae6a15 100644 +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -77,7 +77,9 @@ extern const struct consw prom_con; /* SPARC PROM console */ + int con_is_bound(const struct consw *csw); + int register_con_driver(const struct consw *csw, int first, int last); + int unregister_con_driver(const struct consw *csw); ++int do_unregister_con_driver(const struct consw *csw); + int take_over_console(const struct consw *sw, int first, int last, int deflt); ++int do_take_over_console(const struct consw *sw, int first, int last, int deflt); + void give_up_console(const struct consw *sw); + #ifdef CONFIG_HW_CONSOLE + int con_debug_enter(struct vc_data *vc); +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 29b6353..a276817 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -2103,6 +2103,7 @@ extern void bd_forget(struct inode *inode); + extern void bdput(struct block_device *); + extern void invalidate_bdev(struct block_device *); + extern int sync_blockdev(struct block_device *bdev); ++extern void kill_bdev(struct block_device *); + extern struct super_block *freeze_bdev(struct block_device *); + extern void emergency_thaw_all(void); + extern int thaw_bdev(struct block_device *bdev, struct super_block *sb); +@@ -2110,6 +2111,7 @@ extern int fsync_bdev(struct block_device *); + #else + static inline void bd_forget(struct inode *inode) {} + static inline int sync_blockdev(struct block_device *bdev) { return 0; } ++static inline void kill_bdev(struct block_device *bdev) {} + static inline void invalidate_bdev(struct block_device *bdev) {} + + static inline struct super_block *freeze_bdev(struct block_device *sb) +diff --git a/include/linux/idr.h b/include/linux/idr.h +index 255491c..52a9da2 100644 +--- a/include/linux/idr.h ++++ b/include/linux/idr.h +@@ -152,4 +152,15 @@ void ida_simple_remove(struct ida *ida, unsigned int id); + + void __init idr_init_cache(void); + ++/** ++ * idr_for_each_entry - iterate over an idr's elements of a given type ++ * @idp: idr handle ++ * @entry: the type * to use as cursor ++ * @id: id entry's key ++ */ ++#define idr_for_each_entry(idp, entry, id) \ ++ for (id = 0, entry = (typeof(entry))idr_get_next((idp), &(id)); \ ++ entry != NULL; \ ++ ++id, entry = (typeof(entry))idr_get_next((idp), &(id))) ++ + #endif /* __IDR_H__ */ +diff --git a/include/linux/kmod.h b/include/linux/kmod.h +index b16f653..f8d4b27 100644 +--- a/include/linux/kmod.h ++++ b/include/linux/kmod.h +@@ -54,6 +54,8 @@ enum umh_wait { + UMH_WAIT_PROC = 1, /* wait for the process to complete */ + }; + ++#define UMH_KILLABLE 4 /* wait for EXEC/PROC killable */ ++ + struct subprocess_info { + struct work_struct work; + struct completion *complete; +diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h +index 1d1b1e1..ee2baf0 100644 +--- a/include/linux/mmu_notifier.h ++++ b/include/linux/mmu_notifier.h +@@ -4,6 +4,7 @@ + #include <linux/list.h> + #include <linux/spinlock.h> + #include <linux/mm_types.h> ++#include <linux/srcu.h> + + struct mmu_notifier; + struct mmu_notifier_ops; +diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h +index 9404854..ce2ab3d 100644 +--- a/include/linux/pps_kernel.h ++++ b/include/linux/pps_kernel.h +@@ -43,7 +43,7 @@ struct pps_source_info { + int event, void *data); /* PPS echo function */ + + struct module *owner; +- struct device *dev; ++ struct device *dev; /* Parent device for device_create */ + }; + + struct pps_event_time { +@@ -69,6 +69,7 @@ struct pps_device { + wait_queue_head_t queue; /* PPS event queue */ + + unsigned int id; /* PPS source unique ID */ ++ void const *lookup_cookie; /* pps_lookup_dev only */ + struct cdev cdev; + struct device *dev; + struct fasync_struct *async_queue; /* fasync method */ +@@ -82,16 +83,26 @@ struct pps_device { + extern struct device_attribute pps_attrs[]; + + /* ++ * Internal functions. ++ * ++ * These are not actually part of the exported API, but this is a ++ * convenient header file to put them in. ++ */ ++ ++extern int pps_register_cdev(struct pps_device *pps); ++extern void pps_unregister_cdev(struct pps_device *pps); ++ ++/* + * Exported functions + */ + + extern struct pps_device *pps_register_source( + struct pps_source_info *info, int default_params); + extern void pps_unregister_source(struct pps_device *pps); +-extern int pps_register_cdev(struct pps_device *pps); +-extern void pps_unregister_cdev(struct pps_device *pps); + extern void pps_event(struct pps_device *pps, + struct pps_event_time *ts, int event, void *data); ++/* Look up a pps device by magic cookie */ ++struct pps_device *pps_lookup_dev(void const *cookie); + + static inline void timespec_to_pps_ktime(struct pps_ktime *kt, + struct timespec ts) +diff --git a/include/linux/pstore.h b/include/linux/pstore.h +index 2ca8cde..9b16969 100644 +--- a/include/linux/pstore.h ++++ b/include/linux/pstore.h +@@ -22,6 +22,8 @@ + #ifndef _LINUX_PSTORE_H + #define _LINUX_PSTORE_H + ++#include <linux/kmsg_dump.h> ++ + /* types */ + enum pstore_type_id { + PSTORE_TYPE_DMESG = 0, +@@ -50,6 +52,7 @@ struct pstore_info { + + #ifdef CONFIG_PSTORE + extern int pstore_register(struct pstore_info *); ++extern bool pstore_cannot_block_path(enum kmsg_dump_reason reason); + extern int pstore_write(enum pstore_type_id type, char *buf, size_t size); + #else + static inline int +@@ -57,6 +60,11 @@ pstore_register(struct pstore_info *psi) + { + return -ENODEV; + } ++static inline bool ++pstore_cannot_block_path(enum kmsg_dump_reason reason) ++{ ++ return false; ++} + static inline int + pstore_write(enum pstore_type_id type, char *buf, size_t size) + { +diff --git a/include/linux/quota.h b/include/linux/quota.h +index cb78556..1162580 100644 +--- a/include/linux/quota.h ++++ b/include/linux/quota.h +@@ -413,6 +413,7 @@ struct quota_module_name { + #define INIT_QUOTA_MODULE_NAMES {\ + {QFMT_VFS_OLD, "quota_v1"},\ + {QFMT_VFS_V0, "quota_v2"},\ ++ {QFMT_VFS_V1, "quota_v2"},\ + {0, NULL}} + + #endif /* __KERNEL__ */ +diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h +index 8bec265..bae516e 100644 +--- a/include/linux/serial_core.h ++++ b/include/linux/serial_core.h +@@ -47,8 +47,8 @@ + #define PORT_U6_16550A 19 /* ST-Ericsson U6xxx internal UART */ + #define PORT_TEGRA 20 /* NVIDIA Tegra internal UART */ + #define PORT_XR17D15X 21 /* Exar XR17D15x UART */ +-#define PORT_BRCM_TRUMANAGE 22 +-#define PORT_MAX_8250 22 /* max port ID */ ++#define PORT_BRCM_TRUMANAGE 25 ++#define PORT_MAX_8250 25 /* max port ID */ + + /* + * ARM specific type numbers. These are not currently guaranteed +diff --git a/include/linux/usb/audio.h b/include/linux/usb/audio.h +index a54b825..6f8b026 100644 +--- a/include/linux/usb/audio.h ++++ b/include/linux/usb/audio.h +@@ -384,14 +384,16 @@ static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_de + int protocol) + { + __u8 control_size = uac_processing_unit_bControlSize(desc, protocol); +- return desc->baSourceID[desc->bNrInPins + control_size]; ++ return *(uac_processing_unit_bmControls(desc, protocol) ++ + control_size); + } + + static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc, + int protocol) + { + __u8 control_size = uac_processing_unit_bControlSize(desc, protocol); +- return &desc->baSourceID[desc->bNrInPins + control_size + 1]; ++ return uac_processing_unit_bmControls(desc, protocol) ++ + control_size + 1; + } + + /* 4.5.2 Class-Specific AS Interface Descriptor */ +diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h +index c2164fa..644921f 100644 +--- a/include/linux/vt_kern.h ++++ b/include/linux/vt_kern.h +@@ -47,6 +47,7 @@ int con_set_cmap(unsigned char __user *cmap); + int con_get_cmap(unsigned char __user *cmap); + void scrollback(struct vc_data *vc, int lines); + void scrollfront(struct vc_data *vc, int lines); ++void clear_buffer_attributes(struct vc_data *vc); + void update_region(struct vc_data *vc, unsigned long start, int count); + void redraw_screen(struct vc_data *vc, int is_switch); + #define update_screen(x) redraw_screen(x, 0) +@@ -131,6 +132,8 @@ void vt_event_post(unsigned int event, unsigned int old, unsigned int new); + int vt_waitactive(int n); + void change_console(struct vc_data *new_vc); + void reset_vc(struct vc_data *vc); ++extern int do_unbind_con_driver(const struct consw *csw, int first, int last, ++ int deflt); + extern int unbind_con_driver(const struct consw *csw, int first, int last, + int deflt); + int vty_init(const struct file_operations *console_fops); +diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h +index e46674d..f9ce2fa 100644 +--- a/include/net/inet6_hashtables.h ++++ b/include/net/inet6_hashtables.h +@@ -28,16 +28,16 @@ + + struct inet_hashinfo; + +-/* I have no idea if this is a good hash for v6 or not. -DaveM */ + static inline unsigned int inet6_ehashfn(struct net *net, + const struct in6_addr *laddr, const u16 lport, + const struct in6_addr *faddr, const __be16 fport) + { +- u32 ports = (lport ^ (__force u16)fport); ++ u32 ports = (((u32)lport) << 16) | (__force u32)fport; + + return jhash_3words((__force u32)laddr->s6_addr32[3], +- (__force u32)faddr->s6_addr32[3], +- ports, inet_ehash_secret + net_hash_mix(net)); ++ ipv6_addr_jhash(faddr), ++ ports, ++ inet_ehash_secret + net_hash_mix(net)); + } + + static inline int inet6_sk_ehashfn(const struct sock *sk) +diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h +index f941964..ee4ee91 100644 +--- a/include/net/inet_sock.h ++++ b/include/net/inet_sock.h +@@ -199,6 +199,7 @@ static inline void inet_sk_copy_descendant(struct sock *sk_to, + extern int inet_sk_rebuild_header(struct sock *sk); + + extern u32 inet_ehash_secret; ++extern u32 ipv6_hash_secret; + extern void build_ehash_secret(void); + + static inline unsigned int inet_ehashfn(struct net *net, +diff --git a/include/net/ipv6.h b/include/net/ipv6.h +index a366a8a..4d549cf 100644 +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -15,6 +15,7 @@ + + #include <linux/ipv6.h> + #include <linux/hardirq.h> ++#include <linux/jhash.h> + #include <net/if_inet6.h> + #include <net/ndisc.h> + #include <net/flow.h> +@@ -386,6 +387,17 @@ struct ip6_create_arg { + void ip6_frag_init(struct inet_frag_queue *q, void *a); + int ip6_frag_match(struct inet_frag_queue *q, void *a); + ++/* more secured version of ipv6_addr_hash() */ ++static inline u32 ipv6_addr_jhash(const struct in6_addr *a) ++{ ++ u32 v = (__force u32)a->s6_addr32[0] ^ (__force u32)a->s6_addr32[1]; ++ ++ return jhash_3words(v, ++ (__force u32)a->s6_addr32[2], ++ (__force u32)a->s6_addr32[3], ++ ipv6_hash_secret); ++} ++ + static inline int ipv6_addr_any(const struct in6_addr *a) + { + return (a->s6_addr32[0] | a->s6_addr32[1] | +diff --git a/include/target/target_core_device.h b/include/target/target_core_device.h +index 2be31ff..6f30e70 100644 +--- a/include/target/target_core_device.h ++++ b/include/target/target_core_device.h +@@ -50,7 +50,7 @@ extern struct se_lun *core_dev_add_lun(struct se_portal_group *, struct se_hba * + extern int core_dev_del_lun(struct se_portal_group *, u32); + extern struct se_lun *core_get_lun_from_tpg(struct se_portal_group *, u32); + extern struct se_lun_acl *core_dev_init_initiator_node_lun_acl(struct se_portal_group *, +- u32, char *, int *); ++ struct se_node_acl *, u32, int *); + extern int core_dev_add_initiator_node_lun_acl(struct se_portal_group *, + struct se_lun_acl *, u32, u32); + extern int core_dev_del_initiator_node_lun_acl(struct se_portal_group *, +diff --git a/kernel/cgroup.c b/kernel/cgroup.c +index b6cacf1..c0739f8 100644 +--- a/kernel/cgroup.c ++++ b/kernel/cgroup.c +@@ -361,12 +361,20 @@ static void __put_css_set(struct css_set *cg, int taskexit) + struct cgroup *cgrp = link->cgrp; + list_del(&link->cg_link_list); + list_del(&link->cgrp_link_list); ++ ++ /* ++ * We may not be holding cgroup_mutex, and if cgrp->count is ++ * dropped to 0 the cgroup can be destroyed at any time, hence ++ * rcu_read_lock is used to keep it alive. ++ */ ++ rcu_read_lock(); + if (atomic_dec_and_test(&cgrp->count) && + notify_on_release(cgrp)) { + if (taskexit) + set_bit(CGRP_RELEASABLE, &cgrp->flags); + check_for_release(cgrp); + } ++ rcu_read_unlock(); + + kfree(link); + } +diff --git a/kernel/cpuset.c b/kernel/cpuset.c +index 84a524b..835eee6 100644 +--- a/kernel/cpuset.c ++++ b/kernel/cpuset.c +@@ -2507,8 +2507,16 @@ void cpuset_print_task_mems_allowed(struct task_struct *tsk) + + dentry = task_cs(tsk)->css.cgroup->dentry; + spin_lock(&cpuset_buffer_lock); +- snprintf(cpuset_name, CPUSET_NAME_LEN, +- dentry ? (const char *)dentry->d_name.name : "/"); ++ ++ if (!dentry) { ++ strcpy(cpuset_name, "/"); ++ } else { ++ spin_lock(&dentry->d_lock); ++ strlcpy(cpuset_name, (const char *)dentry->d_name.name, ++ CPUSET_NAME_LEN); ++ spin_unlock(&dentry->d_lock); ++ } ++ + nodelist_scnprintf(cpuset_nodelist, CPUSET_NODELIST_LEN, + tsk->mems_allowed); + printk(KERN_INFO "%s cpuset=%s mems_allowed=%s\n", +diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c +index 6db7a5e..cdd5607 100644 +--- a/kernel/hrtimer.c ++++ b/kernel/hrtimer.c +@@ -640,21 +640,9 @@ static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) + * and expiry check is done in the hrtimer_interrupt or in the softirq. + */ + static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, +- struct hrtimer_clock_base *base, +- int wakeup) ++ struct hrtimer_clock_base *base) + { +- if (base->cpu_base->hres_active && hrtimer_reprogram(timer, base)) { +- if (wakeup) { +- raw_spin_unlock(&base->cpu_base->lock); +- raise_softirq_irqoff(HRTIMER_SOFTIRQ); +- raw_spin_lock(&base->cpu_base->lock); +- } else +- __raise_softirq_irqoff(HRTIMER_SOFTIRQ); +- +- return 1; +- } +- +- return 0; ++ return base->cpu_base->hres_active && hrtimer_reprogram(timer, base); + } + + static inline ktime_t hrtimer_update_base(struct hrtimer_cpu_base *base) +@@ -735,8 +723,7 @@ static inline int hrtimer_switch_to_hres(void) { return 0; } + static inline void + hrtimer_force_reprogram(struct hrtimer_cpu_base *base, int skip_equal) { } + static inline int hrtimer_enqueue_reprogram(struct hrtimer *timer, +- struct hrtimer_clock_base *base, +- int wakeup) ++ struct hrtimer_clock_base *base) + { + return 0; + } +@@ -995,8 +982,21 @@ int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, + * + * XXX send_remote_softirq() ? + */ +- if (leftmost && new_base->cpu_base == &__get_cpu_var(hrtimer_bases)) +- hrtimer_enqueue_reprogram(timer, new_base, wakeup); ++ if (leftmost && new_base->cpu_base == &__get_cpu_var(hrtimer_bases) ++ && hrtimer_enqueue_reprogram(timer, new_base)) { ++ if (wakeup) { ++ /* ++ * We need to drop cpu_base->lock to avoid a ++ * lock ordering issue vs. rq->lock. ++ */ ++ raw_spin_unlock(&new_base->cpu_base->lock); ++ raise_softirq_irqoff(HRTIMER_SOFTIRQ); ++ local_irq_restore(flags); ++ return ret; ++ } else { ++ __raise_softirq_irqoff(HRTIMER_SOFTIRQ); ++ } ++ } + + unlock_hrtimer_base(timer, &flags); + +diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c +index dc813a9..63633a3 100644 +--- a/kernel/irq/spurious.c ++++ b/kernel/irq/spurious.c +@@ -80,13 +80,11 @@ static int try_one_irq(int irq, struct irq_desc *desc, bool force) + + /* + * All handlers must agree on IRQF_SHARED, so we test just the +- * first. Check for action->next as well. ++ * first. + */ + action = desc->action; + if (!action || !(action->flags & IRQF_SHARED) || +- (action->flags & __IRQF_TIMER) || +- (action->handler(irq, action->dev_id) == IRQ_HANDLED) || +- !action->next) ++ (action->flags & __IRQF_TIMER)) + goto out; + + /* Already running on another processor */ +@@ -104,6 +102,7 @@ static int try_one_irq(int irq, struct irq_desc *desc, bool force) + do { + if (handle_irq_event(desc) == IRQ_HANDLED) + ret = IRQ_HANDLED; ++ /* Make sure that there is still a valid action */ + action = desc->action; + } while ((desc->istate & IRQS_PENDING) && action); + desc->istate &= ~IRQS_POLL_INPROGRESS; +diff --git a/kernel/kmod.c b/kernel/kmod.c +index a4bea97..d6fe08a 100644 +--- a/kernel/kmod.c ++++ b/kernel/kmod.c +@@ -58,6 +58,43 @@ static DEFINE_SPINLOCK(umh_sysctl_lock); + */ + char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe"; + ++static void free_modprobe_argv(struct subprocess_info *info) ++{ ++ kfree(info->argv[3]); /* check call_modprobe() */ ++ kfree(info->argv); ++} ++ ++static int call_modprobe(char *module_name, int wait) ++{ ++ static char *envp[] = { ++ "HOME=/", ++ "TERM=linux", ++ "PATH=/sbin:/usr/sbin:/bin:/usr/bin", ++ NULL ++ }; ++ ++ char **argv = kmalloc(sizeof(char *[5]), GFP_KERNEL); ++ if (!argv) ++ goto out; ++ ++ module_name = kstrdup(module_name, GFP_KERNEL); ++ if (!module_name) ++ goto free_argv; ++ ++ argv[0] = modprobe_path; ++ argv[1] = "-q"; ++ argv[2] = "--"; ++ argv[3] = module_name; /* check free_modprobe_argv() */ ++ argv[4] = NULL; ++ ++ return call_usermodehelper_fns(modprobe_path, argv, envp, ++ wait | UMH_KILLABLE, NULL, free_modprobe_argv, NULL); ++free_argv: ++ kfree(argv); ++out: ++ return -ENOMEM; ++} ++ + /** + * __request_module - try to load a kernel module + * @wait: wait (or not) for the operation to complete +@@ -79,11 +116,6 @@ int __request_module(bool wait, const char *fmt, ...) + char module_name[MODULE_NAME_LEN]; + unsigned int max_modprobes; + int ret; +- char *argv[] = { modprobe_path, "-q", "--", module_name, NULL }; +- static char *envp[] = { "HOME=/", +- "TERM=linux", +- "PATH=/sbin:/usr/sbin:/bin:/usr/bin", +- NULL }; + static atomic_t kmod_concurrent = ATOMIC_INIT(0); + #define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */ + static int kmod_loop_msg; +@@ -126,9 +158,7 @@ int __request_module(bool wait, const char *fmt, ...) + + trace_module_request(module_name, wait, _RET_IP_); + +- ret = call_usermodehelper_fns(modprobe_path, argv, envp, +- wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC, +- NULL, NULL, NULL); ++ ret = call_modprobe(module_name, wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC); + + atomic_dec(&kmod_concurrent); + return ret; +@@ -186,7 +216,7 @@ static int ____call_usermodehelper(void *data) + /* Exec failed? */ + fail: + sub_info->retval = retval; +- do_exit(0); ++ return 0; + } + + void call_usermodehelper_freeinfo(struct subprocess_info *info) +@@ -197,6 +227,19 @@ void call_usermodehelper_freeinfo(struct subprocess_info *info) + } + EXPORT_SYMBOL(call_usermodehelper_freeinfo); + ++static void umh_complete(struct subprocess_info *sub_info) ++{ ++ struct completion *comp = xchg(&sub_info->complete, NULL); ++ /* ++ * See call_usermodehelper_exec(). If xchg() returns NULL ++ * we own sub_info, the UMH_KILLABLE caller has gone away. ++ */ ++ if (comp) ++ complete(comp); ++ else ++ call_usermodehelper_freeinfo(sub_info); ++} ++ + /* Keventd can't block, but this (a child) can. */ + static int wait_for_helper(void *data) + { +@@ -233,7 +276,7 @@ static int wait_for_helper(void *data) + sub_info->retval = ret; + } + +- complete(sub_info->complete); ++ umh_complete(sub_info); + return 0; + } + +@@ -245,6 +288,9 @@ static void __call_usermodehelper(struct work_struct *work) + enum umh_wait wait = sub_info->wait; + pid_t pid; + ++ if (wait != UMH_NO_WAIT) ++ wait &= ~UMH_KILLABLE; ++ + /* CLONE_VFORK: wait until the usermode helper has execve'd + * successfully We need the data structures to stay around + * until that is done. */ +@@ -267,7 +313,7 @@ static void __call_usermodehelper(struct work_struct *work) + case UMH_WAIT_EXEC: + if (pid < 0) + sub_info->retval = pid; +- complete(sub_info->complete); ++ umh_complete(sub_info); + } + } + +@@ -435,9 +481,21 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, + queue_work(khelper_wq, &sub_info->work); + if (wait == UMH_NO_WAIT) /* task has freed sub_info */ + goto unlock; ++ ++ if (wait & UMH_KILLABLE) { ++ retval = wait_for_completion_killable(&done); ++ if (!retval) ++ goto wait_done; ++ ++ /* umh_complete() will see NULL and free sub_info */ ++ if (xchg(&sub_info->complete, NULL)) ++ goto unlock; ++ /* fallthrough, umh_complete() was already called */ ++ } ++ + wait_for_completion(&done); ++wait_done: + retval = sub_info->retval; +- + out: + call_usermodehelper_freeinfo(sub_info); + unlock: +diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c +index e7cb76d..962c291 100644 +--- a/kernel/posix-cpu-timers.c ++++ b/kernel/posix-cpu-timers.c +@@ -1450,8 +1450,10 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, + while (!signal_pending(current)) { + if (timer.it.cpu.expires.sched == 0) { + /* +- * Our timer fired and was reset. ++ * Our timer fired and was reset, below ++ * deletion can not fail. + */ ++ posix_cpu_timer_del(&timer); + spin_unlock_irq(&timer.it_lock); + return 0; + } +@@ -1469,9 +1471,26 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, + * We were interrupted by a signal. + */ + sample_to_timespec(which_clock, timer.it.cpu.expires, rqtp); +- posix_cpu_timer_set(&timer, 0, &zero_it, it); ++ error = posix_cpu_timer_set(&timer, 0, &zero_it, it); ++ if (!error) { ++ /* ++ * Timer is now unarmed, deletion can not fail. ++ */ ++ posix_cpu_timer_del(&timer); ++ } + spin_unlock_irq(&timer.it_lock); + ++ while (error == TIMER_RETRY) { ++ /* ++ * We need to handle case when timer was or is in the ++ * middle of firing. In other cases we already freed ++ * resources. ++ */ ++ spin_lock_irq(&timer.it_lock); ++ error = posix_cpu_timer_del(&timer); ++ spin_unlock_irq(&timer.it_lock); ++ } ++ + if ((it->it_value.tv_sec | it->it_value.tv_nsec) == 0) { + /* + * It actually did fire already. +diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c +index 69185ae..e885be1 100644 +--- a/kernel/posix-timers.c ++++ b/kernel/posix-timers.c +@@ -639,6 +639,13 @@ static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags) + { + struct k_itimer *timr; + ++ /* ++ * timer_t could be any type >= int and we want to make sure any ++ * @timer_id outside positive int range fails lookup. ++ */ ++ if ((unsigned long long)timer_id > INT_MAX) ++ return NULL; ++ + rcu_read_lock(); + timr = idr_find(&posix_timers_id, (int)timer_id); + if (timr) { +diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c +index a650694..9f9aa32 100644 +--- a/kernel/sysctl_binary.c ++++ b/kernel/sysctl_binary.c +@@ -1194,9 +1194,10 @@ static ssize_t bin_dn_node_address(struct file *file, + + /* Convert the decnet address to binary */ + result = -EIO; +- nodep = strchr(buf, '.') + 1; ++ nodep = strchr(buf, '.'); + if (!nodep) + goto out; ++ ++nodep; + + area = simple_strtoul(buf, NULL, 10); + node = simple_strtoul(nodep, NULL, 10); +diff --git a/kernel/timeconst.pl b/kernel/timeconst.pl +index eb51d76..3f42652 100644 +--- a/kernel/timeconst.pl ++++ b/kernel/timeconst.pl +@@ -369,10 +369,8 @@ if ($hz eq '--can') { + die "Usage: $0 HZ\n"; + } + +- @val = @{$canned_values{$hz}}; +- if (!defined(@val)) { +- @val = compute_values($hz); +- } ++ $cv = $canned_values{$hz}; ++ @val = defined($cv) ? @$cv : compute_values($hz); + output($hz, @val); + } + exit 0; +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index 4b1a96b..6c880e8 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -3454,37 +3454,51 @@ static void ftrace_init_module(struct module *mod, + ftrace_process_locs(mod, start, end); + } + +-static int ftrace_module_notify(struct notifier_block *self, +- unsigned long val, void *data) ++static int ftrace_module_notify_enter(struct notifier_block *self, ++ unsigned long val, void *data) + { + struct module *mod = data; + +- switch (val) { +- case MODULE_STATE_COMING: ++ if (val == MODULE_STATE_COMING) + ftrace_init_module(mod, mod->ftrace_callsites, + mod->ftrace_callsites + + mod->num_ftrace_callsites); +- break; +- case MODULE_STATE_GOING: ++ return 0; ++} ++ ++static int ftrace_module_notify_exit(struct notifier_block *self, ++ unsigned long val, void *data) ++{ ++ struct module *mod = data; ++ ++ if (val == MODULE_STATE_GOING) + ftrace_release_mod(mod); +- break; +- } + + return 0; + } + #else +-static int ftrace_module_notify(struct notifier_block *self, +- unsigned long val, void *data) ++static int ftrace_module_notify_enter(struct notifier_block *self, ++ unsigned long val, void *data) ++{ ++ return 0; ++} ++static int ftrace_module_notify_exit(struct notifier_block *self, ++ unsigned long val, void *data) + { + return 0; + } + #endif /* CONFIG_MODULES */ + +-struct notifier_block ftrace_module_nb = { +- .notifier_call = ftrace_module_notify, ++struct notifier_block ftrace_module_enter_nb = { ++ .notifier_call = ftrace_module_notify_enter, + .priority = INT_MAX, /* Run before anything that can use kprobes */ + }; + ++struct notifier_block ftrace_module_exit_nb = { ++ .notifier_call = ftrace_module_notify_exit, ++ .priority = INT_MIN, /* Run after anything that can remove kprobes */ ++}; ++ + extern unsigned long __start_mcount_loc[]; + extern unsigned long __stop_mcount_loc[]; + +@@ -3516,9 +3530,13 @@ void __init ftrace_init(void) + __start_mcount_loc, + __stop_mcount_loc); + +- ret = register_module_notifier(&ftrace_module_nb); ++ ret = register_module_notifier(&ftrace_module_enter_nb); ++ if (ret) ++ pr_warning("Failed to register trace ftrace module enter notifier\n"); ++ ++ ret = register_module_notifier(&ftrace_module_exit_nb); + if (ret) +- pr_warning("Failed to register trace ftrace module notifier\n"); ++ pr_warning("Failed to register trace ftrace module exit notifier\n"); + + set_ftrace_early_filters(); + +diff --git a/kernel/workqueue.c b/kernel/workqueue.c +index 7bf068a..0ad2420 100644 +--- a/kernel/workqueue.c ++++ b/kernel/workqueue.c +@@ -128,6 +128,7 @@ struct worker { + }; + + struct work_struct *current_work; /* L: work being processed */ ++ work_func_t current_func; /* L: current_work's fn */ + struct cpu_workqueue_struct *current_cwq; /* L: current_work's cwq */ + struct list_head scheduled; /* L: scheduled works */ + struct task_struct *task; /* I: worker task */ +@@ -843,7 +844,8 @@ static struct worker *__find_worker_executing_work(struct global_cwq *gcwq, + struct hlist_node *tmp; + + hlist_for_each_entry(worker, tmp, bwh, hentry) +- if (worker->current_work == work) ++ if (worker->current_work == work && ++ worker->current_func == work->func) + return worker; + return NULL; + } +@@ -853,9 +855,27 @@ static struct worker *__find_worker_executing_work(struct global_cwq *gcwq, + * @gcwq: gcwq of interest + * @work: work to find worker for + * +- * Find a worker which is executing @work on @gcwq. This function is +- * identical to __find_worker_executing_work() except that this +- * function calculates @bwh itself. ++ * Find a worker which is executing @work on @gcwq by searching ++ * @gcwq->busy_hash which is keyed by the address of @work. For a worker ++ * to match, its current execution should match the address of @work and ++ * its work function. This is to avoid unwanted dependency between ++ * unrelated work executions through a work item being recycled while still ++ * being executed. ++ * ++ * This is a bit tricky. A work item may be freed once its execution ++ * starts and nothing prevents the freed area from being recycled for ++ * another work item. If the same work item address ends up being reused ++ * before the original execution finishes, workqueue will identify the ++ * recycled work item as currently executing and make it wait until the ++ * current execution finishes, introducing an unwanted dependency. ++ * ++ * This function checks the work item address, work function and workqueue ++ * to avoid false positives. Note that this isn't complete as one may ++ * construct a work function which can introduce dependency onto itself ++ * through a recycled work item. Well, if somebody wants to shoot oneself ++ * in the foot that badly, there's only so much we can do, and if such ++ * deadlock actually occurs, it should be easy to locate the culprit work ++ * function. + * + * CONTEXT: + * spin_lock_irq(gcwq->lock). +@@ -1816,7 +1836,6 @@ __acquires(&gcwq->lock) + struct global_cwq *gcwq = cwq->gcwq; + struct hlist_head *bwh = busy_worker_head(gcwq, work); + bool cpu_intensive = cwq->wq->flags & WQ_CPU_INTENSIVE; +- work_func_t f = work->func; + int work_color; + struct worker *collision; + #ifdef CONFIG_LOCKDEP +@@ -1845,6 +1864,7 @@ __acquires(&gcwq->lock) + debug_work_deactivate(work); + hlist_add_head(&worker->hentry, bwh); + worker->current_work = work; ++ worker->current_func = work->func; + worker->current_cwq = cwq; + work_color = get_work_color(work); + +@@ -1882,7 +1902,7 @@ __acquires(&gcwq->lock) + lock_map_acquire_read(&cwq->wq->lockdep_map); + lock_map_acquire(&lockdep_map); + trace_workqueue_execute_start(work); +- f(work); ++ worker->current_func(work); + /* + * While we must be careful to not use "work" after this, the trace + * point will only record its address. +@@ -1892,11 +1912,10 @@ __acquires(&gcwq->lock) + lock_map_release(&cwq->wq->lockdep_map); + + if (unlikely(in_atomic() || lockdep_depth(current) > 0)) { +- printk(KERN_ERR "BUG: workqueue leaked lock or atomic: " +- "%s/0x%08x/%d\n", +- current->comm, preempt_count(), task_pid_nr(current)); +- printk(KERN_ERR " last function: "); +- print_symbol("%s\n", (unsigned long)f); ++ pr_err("BUG: workqueue leaked lock or atomic: %s/0x%08x/%d\n" ++ " last function: %pf\n", ++ current->comm, preempt_count(), task_pid_nr(current), ++ worker->current_func); + debug_show_held_locks(current); + dump_stack(); + } +@@ -1910,6 +1929,7 @@ __acquires(&gcwq->lock) + /* we're done with it, release */ + hlist_del_init(&worker->hentry); + worker->current_work = NULL; ++ worker->current_func = NULL; + worker->current_cwq = NULL; + cwq_dec_nr_in_flight(cwq, work_color, false); + } +diff --git a/lib/idr.c b/lib/idr.c +index ed055b2..aadc525 100644 +--- a/lib/idr.c ++++ b/lib/idr.c +@@ -39,6 +39,14 @@ + static struct kmem_cache *idr_layer_cache; + static DEFINE_SPINLOCK(simple_ida_lock); + ++/* the maximum ID which can be allocated given idr->layers */ ++static int idr_max(int layers) ++{ ++ int bits = min_t(int, layers * IDR_BITS, MAX_ID_SHIFT); ++ ++ return (1 << bits) - 1; ++} ++ + static struct idr_layer *get_from_free_list(struct idr *idp) + { + struct idr_layer *p; +@@ -223,7 +231,7 @@ build_up: + * Add a new layer to the top of the tree if the requested + * id is larger than the currently allocated space. + */ +- while ((layers < (MAX_LEVEL - 1)) && (id >= (1 << (layers*IDR_BITS)))) { ++ while (id > idr_max(layers)) { + layers++; + if (!p->count) { + /* special case: if the tree is currently empty, +@@ -265,7 +273,7 @@ build_up: + + static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id) + { +- struct idr_layer *pa[MAX_LEVEL]; ++ struct idr_layer *pa[MAX_LEVEL + 1]; + int id; + + id = idr_get_empty_slot(idp, starting_id, pa); +@@ -357,7 +365,7 @@ static void idr_remove_warning(int id) + static void sub_remove(struct idr *idp, int shift, int id) + { + struct idr_layer *p = idp->top; +- struct idr_layer **pa[MAX_LEVEL]; ++ struct idr_layer **pa[MAX_LEVEL + 1]; + struct idr_layer ***paa = &pa[0]; + struct idr_layer *to_free; + int n; +@@ -451,16 +459,16 @@ void idr_remove_all(struct idr *idp) + int n, id, max; + int bt_mask; + struct idr_layer *p; +- struct idr_layer *pa[MAX_LEVEL]; ++ struct idr_layer *pa[MAX_LEVEL + 1]; + struct idr_layer **paa = &pa[0]; + + n = idp->layers * IDR_BITS; + p = idp->top; + rcu_assign_pointer(idp->top, NULL); +- max = 1 << n; ++ max = idr_max(idp->layers); + + id = 0; +- while (id < max) { ++ while (id >= 0 && id <= max) { + while (n > IDR_BITS && p) { + n -= IDR_BITS; + *paa++ = p; +@@ -519,7 +527,7 @@ void *idr_find(struct idr *idp, int id) + /* Mask off upper bits we don't use for the search. */ + id &= MAX_ID_MASK; + +- if (id >= (1 << n)) ++ if (id > idr_max(p->layer + 1)) + return NULL; + BUG_ON(n == 0); + +@@ -555,15 +563,15 @@ int idr_for_each(struct idr *idp, + { + int n, id, max, error = 0; + struct idr_layer *p; +- struct idr_layer *pa[MAX_LEVEL]; ++ struct idr_layer *pa[MAX_LEVEL + 1]; + struct idr_layer **paa = &pa[0]; + + n = idp->layers * IDR_BITS; + p = rcu_dereference_raw(idp->top); +- max = 1 << n; ++ max = idr_max(idp->layers); + + id = 0; +- while (id < max) { ++ while (id >= 0 && id <= max) { + while (n > 0 && p) { + n -= IDR_BITS; + *paa++ = p; +@@ -595,23 +603,25 @@ EXPORT_SYMBOL(idr_for_each); + * Returns pointer to registered object with id, which is next number to + * given id. After being looked up, *@nextidp will be updated for the next + * iteration. ++ * ++ * This function can be called under rcu_read_lock(), given that the leaf ++ * pointers lifetimes are correctly managed. + */ +- + void *idr_get_next(struct idr *idp, int *nextidp) + { +- struct idr_layer *p, *pa[MAX_LEVEL]; ++ struct idr_layer *p, *pa[MAX_LEVEL + 1]; + struct idr_layer **paa = &pa[0]; + int id = *nextidp; + int n, max; + + /* find first ent */ +- n = idp->layers * IDR_BITS; +- max = 1 << n; + p = rcu_dereference_raw(idp->top); + if (!p) + return NULL; ++ n = (p->layer + 1) * IDR_BITS; ++ max = idr_max(p->layer + 1); + +- while (id < max) { ++ while (id >= 0 && id <= max) { + while (n > 0 && p) { + n -= IDR_BITS; + *paa++ = p; +@@ -623,7 +633,14 @@ void *idr_get_next(struct idr *idp, int *nextidp) + return p; + } + +- id += 1 << n; ++ /* ++ * Proceed to the next layer at the current level. Unlike ++ * idr_for_each(), @id isn't guaranteed to be aligned to ++ * layer boundary at this point and adding 1 << n may ++ * incorrectly skip IDs. Make sure we jump to the ++ * beginning of the next layer using round_up(). ++ */ ++ id = round_up(id + 1, 1 << n); + while (n < fls(id)) { + n += IDR_BITS; + p = *--paa; +@@ -778,7 +795,7 @@ EXPORT_SYMBOL(ida_pre_get); + */ + int ida_get_new_above(struct ida *ida, int starting_id, int *p_id) + { +- struct idr_layer *pa[MAX_LEVEL]; ++ struct idr_layer *pa[MAX_LEVEL + 1]; + struct ida_bitmap *bitmap; + unsigned long flags; + int idr_id = starting_id / IDA_BITMAP_BITS; +diff --git a/mm/fadvise.c b/mm/fadvise.c +index 8d723c9..35b2bb0 100644 +--- a/mm/fadvise.c ++++ b/mm/fadvise.c +@@ -17,6 +17,7 @@ + #include <linux/fadvise.h> + #include <linux/writeback.h> + #include <linux/syscalls.h> ++#include <linux/swap.h> + + #include <asm/unistd.h> + +@@ -123,9 +124,22 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice) + start_index = (offset+(PAGE_CACHE_SIZE-1)) >> PAGE_CACHE_SHIFT; + end_index = (endbyte >> PAGE_CACHE_SHIFT); + +- if (end_index >= start_index) +- invalidate_mapping_pages(mapping, start_index, ++ if (end_index >= start_index) { ++ unsigned long count = invalidate_mapping_pages(mapping, ++ start_index, end_index); ++ ++ /* ++ * If fewer pages were invalidated than expected then ++ * it is possible that some of the pages were on ++ * a per-cpu pagevec for a remote CPU. Drain all ++ * pagevecs and try again. ++ */ ++ if (count < (end_index - start_index + 1)) { ++ lru_add_drain_all(); ++ invalidate_mapping_pages(mapping, start_index, + end_index); ++ } ++ } + break; + default: + ret = -EINVAL; +diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c +index 862b608..8d1ca2d 100644 +--- a/mm/mmu_notifier.c ++++ b/mm/mmu_notifier.c +@@ -14,10 +14,14 @@ + #include <linux/export.h> + #include <linux/mm.h> + #include <linux/err.h> ++#include <linux/srcu.h> + #include <linux/rcupdate.h> + #include <linux/sched.h> + #include <linux/slab.h> + ++/* global SRCU for all MMs */ ++static struct srcu_struct srcu; ++ + /* + * This function can't run concurrently against mmu_notifier_register + * because mm->mm_users > 0 during mmu_notifier_register and exit_mmap +@@ -25,58 +29,61 @@ + * in parallel despite there being no task using this mm any more, + * through the vmas outside of the exit_mmap context, such as with + * vmtruncate. This serializes against mmu_notifier_unregister with +- * the mmu_notifier_mm->lock in addition to RCU and it serializes +- * against the other mmu notifiers with RCU. struct mmu_notifier_mm ++ * the mmu_notifier_mm->lock in addition to SRCU and it serializes ++ * against the other mmu notifiers with SRCU. struct mmu_notifier_mm + * can't go away from under us as exit_mmap holds an mm_count pin + * itself. + */ + void __mmu_notifier_release(struct mm_struct *mm) + { + struct mmu_notifier *mn; +- struct hlist_node *n; ++ int id; + + /* +- * RCU here will block mmu_notifier_unregister until +- * ->release returns. ++ * srcu_read_lock() here will block synchronize_srcu() in ++ * mmu_notifier_unregister() until all registered ++ * ->release() callouts this function makes have ++ * returned. + */ +- rcu_read_lock(); +- hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) +- /* +- * if ->release runs before mmu_notifier_unregister it +- * must be handled as it's the only way for the driver +- * to flush all existing sptes and stop the driver +- * from establishing any more sptes before all the +- * pages in the mm are freed. +- */ +- if (mn->ops->release) +- mn->ops->release(mn, mm); +- rcu_read_unlock(); +- ++ id = srcu_read_lock(&srcu); + spin_lock(&mm->mmu_notifier_mm->lock); + while (unlikely(!hlist_empty(&mm->mmu_notifier_mm->list))) { + mn = hlist_entry(mm->mmu_notifier_mm->list.first, + struct mmu_notifier, + hlist); ++ + /* +- * We arrived before mmu_notifier_unregister so +- * mmu_notifier_unregister will do nothing other than +- * to wait ->release to finish and +- * mmu_notifier_unregister to return. ++ * Unlink. This will prevent mmu_notifier_unregister() ++ * from also making the ->release() callout. + */ + hlist_del_init_rcu(&mn->hlist); ++ spin_unlock(&mm->mmu_notifier_mm->lock); ++ ++ /* ++ * Clear sptes. (see 'release' description in mmu_notifier.h) ++ */ ++ if (mn->ops->release) ++ mn->ops->release(mn, mm); ++ ++ spin_lock(&mm->mmu_notifier_mm->lock); + } + spin_unlock(&mm->mmu_notifier_mm->lock); + + /* +- * synchronize_rcu here prevents mmu_notifier_release to +- * return to exit_mmap (which would proceed freeing all pages +- * in the mm) until the ->release method returns, if it was +- * invoked by mmu_notifier_unregister. +- * +- * The mmu_notifier_mm can't go away from under us because one +- * mm_count is hold by exit_mmap. ++ * All callouts to ->release() which we have done are complete. ++ * Allow synchronize_srcu() in mmu_notifier_unregister() to complete ++ */ ++ srcu_read_unlock(&srcu, id); ++ ++ /* ++ * mmu_notifier_unregister() may have unlinked a notifier and may ++ * still be calling out to it. Additionally, other notifiers ++ * may have been active via vmtruncate() et. al. Block here ++ * to ensure that all notifier callouts for this mm have been ++ * completed and the sptes are really cleaned up before returning ++ * to exit_mmap(). + */ +- synchronize_rcu(); ++ synchronize_srcu(&srcu); + } + + /* +@@ -89,14 +96,14 @@ int __mmu_notifier_clear_flush_young(struct mm_struct *mm, + { + struct mmu_notifier *mn; + struct hlist_node *n; +- int young = 0; ++ int young = 0, id; + +- rcu_read_lock(); ++ id = srcu_read_lock(&srcu); + hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) { + if (mn->ops->clear_flush_young) + young |= mn->ops->clear_flush_young(mn, mm, address); + } +- rcu_read_unlock(); ++ srcu_read_unlock(&srcu, id); + + return young; + } +@@ -106,9 +113,9 @@ int __mmu_notifier_test_young(struct mm_struct *mm, + { + struct mmu_notifier *mn; + struct hlist_node *n; +- int young = 0; ++ int young = 0, id; + +- rcu_read_lock(); ++ id = srcu_read_lock(&srcu); + hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) { + if (mn->ops->test_young) { + young = mn->ops->test_young(mn, mm, address); +@@ -116,7 +123,7 @@ int __mmu_notifier_test_young(struct mm_struct *mm, + break; + } + } +- rcu_read_unlock(); ++ srcu_read_unlock(&srcu, id); + + return young; + } +@@ -126,8 +133,9 @@ void __mmu_notifier_change_pte(struct mm_struct *mm, unsigned long address, + { + struct mmu_notifier *mn; + struct hlist_node *n; ++ int id; + +- rcu_read_lock(); ++ id = srcu_read_lock(&srcu); + hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) { + if (mn->ops->change_pte) + mn->ops->change_pte(mn, mm, address, pte); +@@ -138,7 +146,7 @@ void __mmu_notifier_change_pte(struct mm_struct *mm, unsigned long address, + else if (mn->ops->invalidate_page) + mn->ops->invalidate_page(mn, mm, address); + } +- rcu_read_unlock(); ++ srcu_read_unlock(&srcu, id); + } + + void __mmu_notifier_invalidate_page(struct mm_struct *mm, +@@ -146,13 +154,14 @@ void __mmu_notifier_invalidate_page(struct mm_struct *mm, + { + struct mmu_notifier *mn; + struct hlist_node *n; ++ int id; + +- rcu_read_lock(); ++ id = srcu_read_lock(&srcu); + hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) { + if (mn->ops->invalidate_page) + mn->ops->invalidate_page(mn, mm, address); + } +- rcu_read_unlock(); ++ srcu_read_unlock(&srcu, id); + } + + void __mmu_notifier_invalidate_range_start(struct mm_struct *mm, +@@ -160,13 +169,14 @@ void __mmu_notifier_invalidate_range_start(struct mm_struct *mm, + { + struct mmu_notifier *mn; + struct hlist_node *n; ++ int id; + +- rcu_read_lock(); ++ id = srcu_read_lock(&srcu); + hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) { + if (mn->ops->invalidate_range_start) + mn->ops->invalidate_range_start(mn, mm, start, end); + } +- rcu_read_unlock(); ++ srcu_read_unlock(&srcu, id); + } + + void __mmu_notifier_invalidate_range_end(struct mm_struct *mm, +@@ -174,13 +184,14 @@ void __mmu_notifier_invalidate_range_end(struct mm_struct *mm, + { + struct mmu_notifier *mn; + struct hlist_node *n; ++ int id; + +- rcu_read_lock(); ++ id = srcu_read_lock(&srcu); + hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) { + if (mn->ops->invalidate_range_end) + mn->ops->invalidate_range_end(mn, mm, start, end); + } +- rcu_read_unlock(); ++ srcu_read_unlock(&srcu, id); + } + + static int do_mmu_notifier_register(struct mmu_notifier *mn, +@@ -192,6 +203,12 @@ static int do_mmu_notifier_register(struct mmu_notifier *mn, + + BUG_ON(atomic_read(&mm->mm_users) <= 0); + ++ /* ++ * Verify that mmu_notifier_init() already run and the global srcu is ++ * initialized. ++ */ ++ BUG_ON(!srcu.per_cpu_ref); ++ + ret = -ENOMEM; + mmu_notifier_mm = kmalloc(sizeof(struct mmu_notifier_mm), GFP_KERNEL); + if (unlikely(!mmu_notifier_mm)) +@@ -274,8 +291,8 @@ void __mmu_notifier_mm_destroy(struct mm_struct *mm) + /* + * This releases the mm_count pin automatically and frees the mm + * structure if it was the last user of it. It serializes against +- * running mmu notifiers with RCU and against mmu_notifier_unregister +- * with the unregister lock + RCU. All sptes must be dropped before ++ * running mmu notifiers with SRCU and against mmu_notifier_unregister ++ * with the unregister lock + SRCU. All sptes must be dropped before + * calling mmu_notifier_unregister. ->release or any other notifier + * method may be invoked concurrently with mmu_notifier_unregister, + * and only after mmu_notifier_unregister returned we're guaranteed +@@ -285,35 +302,43 @@ void mmu_notifier_unregister(struct mmu_notifier *mn, struct mm_struct *mm) + { + BUG_ON(atomic_read(&mm->mm_count) <= 0); + ++ spin_lock(&mm->mmu_notifier_mm->lock); + if (!hlist_unhashed(&mn->hlist)) { +- /* +- * RCU here will force exit_mmap to wait ->release to finish +- * before freeing the pages. +- */ +- rcu_read_lock(); ++ int id; + + /* +- * exit_mmap will block in mmu_notifier_release to +- * guarantee ->release is called before freeing the +- * pages. ++ * Ensure we synchronize up with __mmu_notifier_release(). + */ ++ id = srcu_read_lock(&srcu); ++ ++ hlist_del_rcu(&mn->hlist); ++ spin_unlock(&mm->mmu_notifier_mm->lock); ++ + if (mn->ops->release) + mn->ops->release(mn, mm); +- rcu_read_unlock(); + +- spin_lock(&mm->mmu_notifier_mm->lock); +- hlist_del_rcu(&mn->hlist); ++ /* ++ * Allow __mmu_notifier_release() to complete. ++ */ ++ srcu_read_unlock(&srcu, id); ++ } else + spin_unlock(&mm->mmu_notifier_mm->lock); +- } + + /* +- * Wait any running method to finish, of course including +- * ->release if it was run by mmu_notifier_relase instead of us. ++ * Wait for any running method to finish, including ->release() if it ++ * was run by __mmu_notifier_release() instead of us. + */ +- synchronize_rcu(); ++ synchronize_srcu(&srcu); + + BUG_ON(atomic_read(&mm->mm_count) <= 0); + + mmdrop(mm); + } + EXPORT_SYMBOL_GPL(mmu_notifier_unregister); ++ ++static int __init mmu_notifier_init(void) ++{ ++ return init_srcu_struct(&srcu); ++} ++ ++module_init(mmu_notifier_init); +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 4d3a697..5c028e2 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -4253,10 +4253,11 @@ static void __meminit calculate_node_totalpages(struct pglist_data *pgdat, + * round what is now in bits to nearest long in bits, then return it in + * bytes. + */ +-static unsigned long __init usemap_size(unsigned long zonesize) ++static unsigned long __init usemap_size(unsigned long zone_start_pfn, unsigned long zonesize) + { + unsigned long usemapsize; + ++ zonesize += zone_start_pfn & (pageblock_nr_pages-1); + usemapsize = roundup(zonesize, pageblock_nr_pages); + usemapsize = usemapsize >> pageblock_order; + usemapsize *= NR_PAGEBLOCK_BITS; +@@ -4266,17 +4267,19 @@ static unsigned long __init usemap_size(unsigned long zonesize) + } + + static void __init setup_usemap(struct pglist_data *pgdat, +- struct zone *zone, unsigned long zonesize) ++ struct zone *zone, ++ unsigned long zone_start_pfn, ++ unsigned long zonesize) + { +- unsigned long usemapsize = usemap_size(zonesize); ++ unsigned long usemapsize = usemap_size(zone_start_pfn, zonesize); + zone->pageblock_flags = NULL; + if (usemapsize) + zone->pageblock_flags = alloc_bootmem_node_nopanic(pgdat, + usemapsize); + } + #else +-static inline void setup_usemap(struct pglist_data *pgdat, +- struct zone *zone, unsigned long zonesize) {} ++static inline void setup_usemap(struct pglist_data *pgdat, struct zone *zone, ++ unsigned long zone_start_pfn, unsigned long zonesize) {} + #endif /* CONFIG_SPARSEMEM */ + + #ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE +@@ -4401,7 +4404,7 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat, + continue; + + set_pageblock_order(); +- setup_usemap(pgdat, zone, size); ++ setup_usemap(pgdat, zone, zone_start_pfn, size); + ret = init_currently_empty_zone(zone, zone_start_pfn, + size, MEMMAP_EARLY); + BUG_ON(ret); +diff --git a/mm/shmem.c b/mm/shmem.c +index 12b9e80..a78acf0 100644 +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -2121,6 +2121,7 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data) + unsigned long inodes; + int error = -EINVAL; + ++ config.mpol = NULL; + if (shmem_parse_options(data, &config, true)) + return error; + +@@ -2145,8 +2146,13 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data) + sbinfo->max_inodes = config.max_inodes; + sbinfo->free_inodes = config.max_inodes - inodes; + +- mpol_put(sbinfo->mpol); +- sbinfo->mpol = config.mpol; /* transfers initial ref */ ++ /* ++ * Preserve previous mempolicy unless mpol remount option was specified. ++ */ ++ if (config.mpol) { ++ mpol_put(sbinfo->mpol); ++ sbinfo->mpol = config.mpol; /* transfers initial ref */ ++ } + out: + spin_unlock(&sbinfo->stat_lock); + return error; +diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c +index e16aade..718cbe8 100644 +--- a/net/bridge/br_stp_bpdu.c ++++ b/net/bridge/br_stp_bpdu.c +@@ -16,6 +16,7 @@ + #include <linux/etherdevice.h> + #include <linux/llc.h> + #include <linux/slab.h> ++#include <linux/pkt_sched.h> + #include <net/net_namespace.h> + #include <net/llc.h> + #include <net/llc_pdu.h> +@@ -40,6 +41,7 @@ static void br_send_bpdu(struct net_bridge_port *p, + + skb->dev = p->dev; + skb->protocol = htons(ETH_P_802_2); ++ skb->priority = TC_PRIO_CONTROL; + + skb_reserve(skb, LLC_RESERVE); + memcpy(__skb_put(skb, length), data, length); +diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c +index 1b5096a..5d228de 100644 +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -226,8 +226,12 @@ EXPORT_SYMBOL(inet_listen); + u32 inet_ehash_secret __read_mostly; + EXPORT_SYMBOL(inet_ehash_secret); + ++u32 ipv6_hash_secret __read_mostly; ++EXPORT_SYMBOL(ipv6_hash_secret); ++ + /* +- * inet_ehash_secret must be set exactly once ++ * inet_ehash_secret must be set exactly once, and to a non nul value ++ * ipv6_hash_secret must be set exactly once. + */ + void build_ehash_secret(void) + { +@@ -237,7 +241,8 @@ void build_ehash_secret(void) + get_random_bytes(&rnd, sizeof(rnd)); + } while (rnd == 0); + +- cmpxchg(&inet_ehash_secret, 0, rnd); ++ if (cmpxchg(&inet_ehash_secret, 0, rnd) == 0) ++ get_random_bytes(&ipv6_hash_secret, sizeof(ipv6_hash_secret)); + } + EXPORT_SYMBOL(build_ehash_secret); + +diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c +index 43d4c3b..294a380 100644 +--- a/net/ipv4/ping.c ++++ b/net/ipv4/ping.c +@@ -321,8 +321,8 @@ void ping_err(struct sk_buff *skb, u32 info) + struct iphdr *iph = (struct iphdr *)skb->data; + struct icmphdr *icmph = (struct icmphdr *)(skb->data+(iph->ihl<<2)); + struct inet_sock *inet_sock; +- int type = icmph->type; +- int code = icmph->code; ++ int type = icmp_hdr(skb)->type; ++ int code = icmp_hdr(skb)->code; + struct net *net = dev_net(skb->dev); + struct sock *sk; + int harderr; +diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c +index 3282453..9acee9d 100644 +--- a/net/sunrpc/svc_xprt.c ++++ b/net/sunrpc/svc_xprt.c +@@ -816,7 +816,6 @@ static void svc_age_temp_xprts(unsigned long closure) + struct svc_serv *serv = (struct svc_serv *)closure; + struct svc_xprt *xprt; + struct list_head *le, *next; +- LIST_HEAD(to_be_aged); + + dprintk("svc_age_temp_xprts\n"); + +@@ -837,25 +836,15 @@ static void svc_age_temp_xprts(unsigned long closure) + if (atomic_read(&xprt->xpt_ref.refcount) > 1 || + test_bit(XPT_BUSY, &xprt->xpt_flags)) + continue; +- svc_xprt_get(xprt); +- list_move(le, &to_be_aged); ++ list_del_init(le); + set_bit(XPT_CLOSE, &xprt->xpt_flags); + set_bit(XPT_DETACHED, &xprt->xpt_flags); +- } +- spin_unlock_bh(&serv->sv_lock); +- +- while (!list_empty(&to_be_aged)) { +- le = to_be_aged.next; +- /* fiddling the xpt_list node is safe 'cos we're XPT_DETACHED */ +- list_del_init(le); +- xprt = list_entry(le, struct svc_xprt, xpt_list); +- + dprintk("queuing xprt %p for closing\n", xprt); + + /* a thread will dequeue and close it soon */ + svc_xprt_enqueue(xprt); +- svc_xprt_put(xprt); + } ++ spin_unlock_bh(&serv->sv_lock); + + mod_timer(&serv->sv_temptimer, jiffies + svc_conn_age_period * HZ); + } +diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c +index 193ce81..42b876d 100644 +--- a/sound/drivers/aloop.c ++++ b/sound/drivers/aloop.c +@@ -287,12 +287,14 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) + loopback_active_notify(dpcm); + break; + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: ++ case SNDRV_PCM_TRIGGER_SUSPEND: + spin_lock(&cable->lock); + cable->pause |= stream; + spin_unlock(&cable->lock); + loopback_timer_stop(dpcm); + break; + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: ++ case SNDRV_PCM_TRIGGER_RESUME: + spin_lock(&cable->lock); + dpcm->last_jiffies = jiffies; + cable->pause &= ~stream; +@@ -552,7 +554,8 @@ static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream) + static struct snd_pcm_hardware loopback_pcm_hardware = + { + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | +- SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE), ++ SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE | ++ SNDRV_PCM_INFO_RESUME), + .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE | + SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE), +diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c +index ef85ac5..be662c9 100644 +--- a/sound/pci/ali5451/ali5451.c ++++ b/sound/pci/ali5451/ali5451.c +@@ -1435,7 +1435,7 @@ static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream) + + spin_lock(&codec->reg_lock); + if (!pvoice->running) { +- spin_unlock_irq(&codec->reg_lock); ++ spin_unlock(&codec->reg_lock); + return 0; + } + outb(pvoice->number, ALI_REG(codec, ALI_GC_CIR)); +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index bde2615..3c8bc6e 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -918,8 +918,12 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, + if (!static_hdmi_pcm && eld->eld_valid) { + snd_hdmi_eld_update_pcm_info(eld, hinfo); + if (hinfo->channels_min > hinfo->channels_max || +- !hinfo->rates || !hinfo->formats) ++ !hinfo->rates || !hinfo->formats) { ++ per_cvt->assigned = 0; ++ hinfo->nid = 0; ++ snd_hda_spdif_ctls_unassign(codec, pin_idx); + return -ENODEV; ++ } + } + + /* Store the updated parameters */ +@@ -983,6 +987,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) + "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", + codec->addr, pin_nid, eld->monitor_present, eld_valid); + ++ eld->eld_valid = false; + if (eld_valid) { + if (!snd_hdmi_get_eld(eld, codec, pin_nid)) + snd_hdmi_show_eld(eld); +diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c +index 21bcb47..62075a5 100644 +--- a/sound/pci/rme32.c ++++ b/sound/pci/rme32.c +@@ -1017,7 +1017,7 @@ static int snd_rme32_capture_close(struct snd_pcm_substream *substream) + spin_lock_irq(&rme32->lock); + rme32->capture_substream = NULL; + rme32->capture_periodsize = 0; +- spin_unlock(&rme32->lock); ++ spin_unlock_irq(&rme32->lock); + return 0; + } + +diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h +index 32d2a21..4e25148 100644 +--- a/sound/usb/quirks-table.h ++++ b/sound/usb/quirks-table.h +@@ -1624,7 +1624,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + /* .vendor_name = "Roland", */ + /* .product_name = "A-PRO", */ +- .ifnum = 1, ++ .ifnum = 0, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = & (const struct snd_usb_midi_endpoint_info) { + .out_cables = 0x0003, diff --git a/3.2.39/4420_grsecurity-2.9.1-3.2.39-201303012254.patch b/3.2.40/4420_grsecurity-2.9.1-3.2.40-201303082037.patch index 12bbb30..774963f 100644 --- a/3.2.39/4420_grsecurity-2.9.1-3.2.39-201303012254.patch +++ b/3.2.40/4420_grsecurity-2.9.1-3.2.40-201303082037.patch @@ -194,10 +194,10 @@ index dfa6fc6..65f7dbe 100644 +zconf.lex.c zoffset.h diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt -index 81c287f..8c5ad74 100644 +index ddbf18e..2c5d501 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt -@@ -848,6 +848,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. +@@ -853,6 +853,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted. gpt [EFI] Forces disk with valid GPT signature but invalid Protective MBR to be treated as GPT. @@ -207,7 +207,7 @@ index 81c287f..8c5ad74 100644 hashdist= [KNL,NUMA] Large hashes allocated during boot are distributed across NUMA nodes. Defaults on for 64-bit NUMA, off otherwise. -@@ -1935,6 +1938,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted. +@@ -1940,6 +1943,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted. the specified number of seconds. This is to be used if your oopses keep scrolling off the screen. @@ -255,7 +255,7 @@ index 88fd7f5..b318a78 100644 ============================================================== diff --git a/Makefile b/Makefile -index 0fceb8b..feec909 100644 +index 47af1e9..e2ebb6d 100644 --- a/Makefile +++ b/Makefile @@ -245,8 +245,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ @@ -1517,6 +1517,18 @@ index ca94653..6ac0d56 100644 #ifdef MULTI_USER extern struct cpu_user_fns cpu_user; +diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h +index 3e08fd3..3f14f89 100644 +--- a/arch/arm/include/asm/pgalloc.h ++++ b/arch/arm/include/asm/pgalloc.h +@@ -31,6 +31,7 @@ + #define pmd_alloc_one(mm,addr) ({ BUG(); ((pmd_t *)2); }) + #define pmd_free(mm, pmd) do { } while (0) + #define pgd_populate(mm,pmd,pte) BUG() ++#define pgd_populate_kernel(mm,pmd,pte) BUG() + + extern pgd_t *pgd_alloc(struct mm_struct *mm); + extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index 96187ff..7a9b049 100644 --- a/arch/arm/include/asm/ptrace.h @@ -3616,10 +3628,10 @@ index fc987a1..6e068ef 100644 #endif diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h -index 22dadeb..f6c2be4 100644 +index 9d35a3e..556001f 100644 --- a/arch/parisc/include/asm/pgtable.h +++ b/arch/parisc/include/asm/pgtable.h -@@ -210,6 +210,17 @@ struct vm_area_struct; +@@ -216,6 +216,17 @@ extern void purge_tlb_entries(struct mm_struct *, unsigned long); #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED) #define PAGE_COPY PAGE_EXECREAD #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED) @@ -8277,7 +8289,7 @@ index ad8f795..2c7eec6 100644 /* * Memory returned by kmalloc() may be used for DMA, so we must make diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig -index efb4294..7c35a85 100644 +index 9a42703..fd885e7 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -235,7 +235,7 @@ config X86_HT @@ -12085,7 +12097,7 @@ index cb00ccc..17e9054 100644 /* diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h -index 884507e..4afeb15 100644 +index 6be9909..4afeb15 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -44,6 +44,7 @@ extern struct mm_struct *pgd_page_get_mm(struct page *page); @@ -12148,19 +12160,7 @@ index 884507e..4afeb15 100644 static inline int pte_dirty(pte_t pte) { return pte_flags(pte) & _PAGE_DIRTY; -@@ -142,6 +182,11 @@ static inline unsigned long pmd_pfn(pmd_t pmd) - return (pmd_val(pmd) & PTE_PFN_MASK) >> PAGE_SHIFT; - } - -+static inline unsigned long pud_pfn(pud_t pud) -+{ -+ return (pud_val(pud) & PTE_PFN_MASK) >> PAGE_SHIFT; -+} -+ - #define pte_page(pte) pfn_to_page(pte_pfn(pte)) - - static inline int pmd_large(pmd_t pte) -@@ -195,9 +240,29 @@ static inline pte_t pte_wrprotect(pte_t pte) +@@ -200,9 +240,29 @@ static inline pte_t pte_wrprotect(pte_t pte) return pte_clear_flags(pte, _PAGE_RW); } @@ -12191,7 +12191,7 @@ index 884507e..4afeb15 100644 } static inline pte_t pte_mkdirty(pte_t pte) -@@ -389,6 +454,15 @@ pte_t *populate_extra_pte(unsigned long vaddr); +@@ -394,6 +454,15 @@ pte_t *populate_extra_pte(unsigned long vaddr); #endif #ifndef __ASSEMBLY__ @@ -12207,7 +12207,7 @@ index 884507e..4afeb15 100644 #include <linux/mm_types.h> static inline int pte_none(pte_t pte) -@@ -565,7 +639,7 @@ static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address) +@@ -570,7 +639,7 @@ static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address) static inline int pgd_bad(pgd_t pgd) { @@ -12216,7 +12216,7 @@ index 884507e..4afeb15 100644 } static inline int pgd_none(pgd_t pgd) -@@ -588,7 +662,12 @@ static inline int pgd_none(pgd_t pgd) +@@ -593,7 +662,12 @@ static inline int pgd_none(pgd_t pgd) * pgd_offset() returns a (pgd_t *) * pgd_index() is used get the offset into the pgd page's array of pgd_t's; */ @@ -12230,7 +12230,7 @@ index 884507e..4afeb15 100644 /* * a shortcut which implies the use of the kernel's pgd, instead * of a process's -@@ -599,6 +678,20 @@ static inline int pgd_none(pgd_t pgd) +@@ -604,6 +678,20 @@ static inline int pgd_none(pgd_t pgd) #define KERNEL_PGD_BOUNDARY pgd_index(PAGE_OFFSET) #define KERNEL_PGD_PTRS (PTRS_PER_PGD - KERNEL_PGD_BOUNDARY) @@ -12251,7 +12251,7 @@ index 884507e..4afeb15 100644 #ifndef __ASSEMBLY__ extern int direct_gbpages; -@@ -763,11 +856,23 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm, +@@ -768,11 +856,23 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm, * dst and src can be on the same page, but the range must not overlap, * and must not cross a page boundary. */ @@ -14659,10 +14659,10 @@ index 5007958..2eba140 100644 .name = "cluster x2apic", .probe = x2apic_cluster_probe, diff --git a/arch/x86/kernel/apic/x2apic_phys.c b/arch/x86/kernel/apic/x2apic_phys.c -index f5373df..b0955f2 100644 +index db4f704..2d4f409 100644 --- a/arch/x86/kernel/apic/x2apic_phys.c +++ b/arch/x86/kernel/apic/x2apic_phys.c -@@ -114,7 +114,7 @@ static int x2apic_phys_probe(void) +@@ -121,7 +121,7 @@ static int x2apic_phys_probe(void) return apic == &apic_x2apic_phys; } @@ -17637,91 +17637,6 @@ index c9a281f..3658fbe 100644 if (probe_kernel_read(code, (void *)ip, MCOUNT_INSN_SIZE)) return -EFAULT; -diff --git a/arch/x86/kernel/head.c b/arch/x86/kernel/head.c -index af0699b..f6c4674 100644 ---- a/arch/x86/kernel/head.c -+++ b/arch/x86/kernel/head.c -@@ -5,8 +5,6 @@ - #include <asm/setup.h> - #include <asm/bios_ebda.h> - --#define BIOS_LOWMEM_KILOBYTES 0x413 -- - /* - * The BIOS places the EBDA/XBDA at the top of conventional - * memory, and usually decreases the reported amount of -@@ -16,17 +14,30 @@ - * chipset: reserve a page before VGA to prevent PCI prefetch - * into it (errata #56). Usually the page is reserved anyways, - * unless you have no PS/2 mouse plugged in. -+ * -+ * This functions is deliberately very conservative. Losing -+ * memory in the bottom megabyte is rarely a problem, as long -+ * as we have enough memory to install the trampoline. Using -+ * memory that is in use by the BIOS or by some DMA device -+ * the BIOS didn't shut down *is* a big problem. - */ -+ -+#define BIOS_LOWMEM_KILOBYTES 0x413 -+#define LOWMEM_CAP 0x9f000U /* Absolute maximum */ -+#define INSANE_CUTOFF 0x20000U /* Less than this = insane */ -+ - void __init reserve_ebda_region(void) - { - unsigned int lowmem, ebda_addr; - -- /* To determine the position of the EBDA and the */ -- /* end of conventional memory, we need to look at */ -- /* the BIOS data area. In a paravirtual environment */ -- /* that area is absent. We'll just have to assume */ -- /* that the paravirt case can handle memory setup */ -- /* correctly, without our help. */ -+ /* -+ * To determine the position of the EBDA and the -+ * end of conventional memory, we need to look at -+ * the BIOS data area. In a paravirtual environment -+ * that area is absent. We'll just have to assume -+ * that the paravirt case can handle memory setup -+ * correctly, without our help. -+ */ - if (paravirt_enabled()) - return; - -@@ -37,19 +48,23 @@ void __init reserve_ebda_region(void) - /* start of EBDA area */ - ebda_addr = get_bios_ebda(); - -- /* Fixup: bios puts an EBDA in the top 64K segment */ -- /* of conventional memory, but does not adjust lowmem. */ -- if ((lowmem - ebda_addr) <= 0x10000) -- lowmem = ebda_addr; -+ /* -+ * Note: some old Dells seem to need 4k EBDA without -+ * reporting so, so just consider the memory above 0x9f000 -+ * to be off limits (bugzilla 2990). -+ */ - -- /* Fixup: bios does not report an EBDA at all. */ -- /* Some old Dells seem to need 4k anyhow (bugzilla 2990) */ -- if ((ebda_addr == 0) && (lowmem >= 0x9f000)) -- lowmem = 0x9f000; -+ /* If the EBDA address is below 128K, assume it is bogus */ -+ if (ebda_addr < INSANE_CUTOFF) -+ ebda_addr = LOWMEM_CAP; - -- /* Paranoia: should never happen, but... */ -- if ((lowmem == 0) || (lowmem >= 0x100000)) -- lowmem = 0x9f000; -+ /* If lowmem is less than 128K, assume it is bogus */ -+ if (lowmem < INSANE_CUTOFF) -+ lowmem = LOWMEM_CAP; -+ -+ /* Use the lower of the lowmem and EBDA markers as the cutoff */ -+ lowmem = min(lowmem, ebda_addr); -+ lowmem = min(lowmem, LOWMEM_CAP); /* Absolute cap */ - - /* reserve all memory between lowmem and the 1MB mark */ - memblock_x86_reserve_range(lowmem, 0x100000, "* BIOS reserved"); diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index 3bb0850..55a56f4 100644 --- a/arch/x86/kernel/head32.c @@ -24972,7 +24887,7 @@ index d0474ad..36e9257 100644 extern u32 pnp_bios_is_utter_crap; pnp_bios_is_utter_crap = 1; diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c -index 5db0490..ec12014 100644 +index 7b73c88..070d4b2 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -13,11 +13,18 @@ @@ -25174,12 +25089,10 @@ index 5db0490..ec12014 100644 printk(KERN_ALERT "BUG: unable to handle kernel "); if (address < PAGE_SIZE) printk(KERN_CONT "NULL pointer dereference"); -@@ -739,12 +820,30 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, - } - #endif +@@ -742,6 +823,25 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, + if (address >= TASK_SIZE) + error_code |= PF_PROT; -- if (unlikely(show_unhandled_signals)) -- show_signal_msg(regs, error_code, address, tsk); +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) + if (pax_is_fetch_fault(regs, error_code, address)) { + @@ -25194,21 +25107,15 @@ index 5db0490..ec12014 100644 + do_group_exit(SIGKILL); + } +#endif - - /* Kernel addresses are always protection faults: */ ++ ++ /* Kernel addresses are always protection faults: */ + if (address >= TASK_SIZE) + error_code |= PF_PROT; + -+ if (show_unhandled_signals) -+ show_signal_msg(regs, error_code, address, tsk); -+ - tsk->thread.cr2 = address; -- tsk->thread.error_code = error_code | (address >= TASK_SIZE); -+ tsk->thread.error_code = error_code; - tsk->thread.trap_no = 14; + if (likely(show_unhandled_signals)) + show_signal_msg(regs, error_code, address, tsk); - force_sig_info_fault(SIGSEGV, si_code, address, tsk, 0); -@@ -835,7 +934,7 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, +@@ -837,7 +937,7 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) { printk(KERN_ERR "MCE: Killing %s:%d due to hardware memory corruption fault at %lx\n", @@ -25217,7 +25124,7 @@ index 5db0490..ec12014 100644 code = BUS_MCEERR_AR; } #endif -@@ -890,6 +989,99 @@ static int spurious_fault_check(unsigned long error_code, pte_t *pte) +@@ -892,6 +992,99 @@ static int spurious_fault_check(unsigned long error_code, pte_t *pte) return 1; } @@ -25317,7 +25224,7 @@ index 5db0490..ec12014 100644 /* * Handle a spurious fault caused by a stale TLB entry. * -@@ -962,6 +1154,9 @@ int show_unhandled_signals = 1; +@@ -964,6 +1157,9 @@ int show_unhandled_signals = 1; static inline int access_error(unsigned long error_code, struct vm_area_struct *vma) { @@ -25327,7 +25234,7 @@ index 5db0490..ec12014 100644 if (error_code & PF_WRITE) { /* write, present and write, not present: */ if (unlikely(!(vma->vm_flags & VM_WRITE))) -@@ -995,18 +1190,32 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code) +@@ -997,18 +1193,32 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code) { struct vm_area_struct *vma; struct task_struct *tsk; @@ -25365,7 +25272,7 @@ index 5db0490..ec12014 100644 /* * Detect and handle instructions that would cause a page fault for -@@ -1067,7 +1276,7 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code) +@@ -1069,7 +1279,7 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code) * User-mode registers count as a user access even for any * potential system fault or CPU buglet: */ @@ -25374,7 +25281,7 @@ index 5db0490..ec12014 100644 local_irq_enable(); error_code |= PF_USER; } else { -@@ -1122,6 +1331,11 @@ retry: +@@ -1124,6 +1334,11 @@ retry: might_sleep(); } @@ -25386,7 +25293,7 @@ index 5db0490..ec12014 100644 vma = find_vma(mm, address); if (unlikely(!vma)) { bad_area(regs, error_code, address); -@@ -1133,18 +1347,24 @@ retry: +@@ -1135,18 +1350,24 @@ retry: bad_area(regs, error_code, address); return; } @@ -25422,7 +25329,7 @@ index 5db0490..ec12014 100644 if (unlikely(expand_stack(vma, address))) { bad_area(regs, error_code, address); return; -@@ -1199,3 +1419,292 @@ good_area: +@@ -1201,3 +1422,292 @@ good_area: up_read(&mm->mmap_sem); } @@ -26435,7 +26342,7 @@ index 29f7c6d..b46b35b 100644 printk(KERN_INFO "Write protecting the kernel text: %luk\n", size >> 10); diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c -index bbaaa00..b5cb517 100644 +index 44b93da..b5cb517 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -75,7 +75,7 @@ early_param("gbpages", parse_direct_gbpages_on); @@ -26583,17 +26490,7 @@ index bbaaa00..b5cb517 100644 /* clear_bss() already clear the empty_zero_page */ reservedpages = 0; -@@ -831,6 +851,9 @@ int kern_addr_valid(unsigned long addr) - if (pud_none(*pud)) - return 0; - -+ if (pud_large(*pud)) -+ return pfn_valid(pud_pfn(*pud)); -+ - pmd = pmd_offset(pud, addr); - if (pmd_none(*pmd)) - return 0; -@@ -853,8 +876,8 @@ int kern_addr_valid(unsigned long addr) +@@ -856,8 +876,8 @@ int kern_addr_valid(unsigned long addr) static struct vm_area_struct gate_vma = { .vm_start = VSYSCALL_START, .vm_end = VSYSCALL_START + (VSYSCALL_MAPPED_PAGES * PAGE_SIZE), @@ -26604,7 +26501,7 @@ index bbaaa00..b5cb517 100644 }; struct vm_area_struct *get_gate_vma(struct mm_struct *mm) -@@ -888,7 +911,7 @@ int in_gate_area_no_mm(unsigned long addr) +@@ -891,7 +911,7 @@ int in_gate_area_no_mm(unsigned long addr) const char *arch_vma_name(struct vm_area_struct *vma) { @@ -31934,6 +31831,34 @@ index 7795d1e..bc6d80a 100644 } static ssize_t port_fops_write(struct file *filp, const char __user *ubuf, +diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c +index 77e1e6c..9d90e8c 100644 +--- a/drivers/connector/cn_proc.c ++++ b/drivers/connector/cn_proc.c +@@ -303,7 +303,13 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, + if (msg->len != sizeof(*mc_op)) + return; + +- mc_op = (enum proc_cn_mcast_op*)msg->data; ++ /* Can only change if privileged. */ ++ if (!capable(CAP_NET_ADMIN)) { ++ err = EPERM; ++ goto out; ++ } ++ ++ mc_op = (enum proc_cn_mcast_op *)msg->data; + switch (*mc_op) { + case PROC_CN_MCAST_LISTEN: + atomic_inc(&proc_event_num_listeners); +@@ -315,6 +321,8 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, + err = EINVAL; + break; + } ++ ++out: + cn_proc_ack(err, msg->seq, msg->ack); + } + diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 987a165..4620e42 100644 --- a/drivers/cpufreq/cpufreq.c @@ -32814,7 +32739,7 @@ index c9339f4..f5e1b9d 100644 int front_offset; } drm_i810_private_t; diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c -index 10fe480..4659c41 100644 +index 5620192..6ca6af4 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -500,7 +500,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) @@ -32954,7 +32879,7 @@ index 93e74fb..4a1182d 100644 INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func); INIT_WORK(&dev_priv->error_work, i915_error_work_func); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c -index 7817429..b6d75d8 100644 +index 2303c2b..c493d4f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2214,7 +2214,7 @@ intel_finish_fb(struct drm_framebuffer *old_fb) @@ -32966,7 +32891,7 @@ index 7817429..b6d75d8 100644 /* Big Hammer, we also need to ensure that any pending * MI_WAIT_FOR_EVENT inside a user batch buffer on the -@@ -6978,8 +6978,7 @@ static void do_intel_finish_page_flip(struct drm_device *dev, +@@ -6986,8 +6986,7 @@ static void do_intel_finish_page_flip(struct drm_device *dev, obj = work->old_fb_obj; @@ -32976,7 +32901,7 @@ index 7817429..b6d75d8 100644 wake_up(&dev_priv->pending_flip_queue); schedule_work(&work->work); -@@ -7188,7 +7187,13 @@ static int intel_gen6_queue_flip(struct drm_device *dev, +@@ -7196,7 +7195,13 @@ static int intel_gen6_queue_flip(struct drm_device *dev, OUT_RING(fb->pitch | obj->tiling_mode); OUT_RING(obj->gtt_offset); @@ -32991,7 +32916,7 @@ index 7817429..b6d75d8 100644 pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; OUT_RING(pf | pipesrc); -@@ -7324,7 +7329,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, +@@ -7332,7 +7337,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, /* Block clients from rendering to the new back buffer until * the flip occurs and the object is no longer visible. */ @@ -33000,7 +32925,7 @@ index 7817429..b6d75d8 100644 ret = dev_priv->display.queue_flip(dev, crtc, fb, obj); if (ret) -@@ -7338,7 +7343,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, +@@ -7346,7 +7351,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, return 0; cleanup_pending: @@ -33009,7 +32934,7 @@ index 7817429..b6d75d8 100644 drm_gem_object_unreference(&work->old_fb_obj->base); drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); -@@ -7472,11 +7477,15 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) +@@ -7480,11 +7485,15 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) if (HAS_PCH_SPLIT(dev)) { if (pipe == 2 && IS_IVYBRIDGE(dev)) intel_crtc->no_pll = true; @@ -33298,10 +33223,10 @@ index a9e33ce..09edd4b 100644 #endif diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c -index 0977849..3355dc2 100644 +index 60d13fe..56badbf 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c -@@ -3064,7 +3064,9 @@ static int evergreen_startup(struct radeon_device *rdev) +@@ -3066,7 +3066,9 @@ static int evergreen_startup(struct radeon_device *rdev) r = evergreen_blit_init(rdev); if (r) { r600_blit_fini(rdev); @@ -33842,10 +33767,10 @@ index 8a8725c..afed796 100644 marker = list_first_entry(&queue->head, struct vmw_marker, head); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c -index 279b863d..cf4afe1 100644 +index a23b63a..4ac8df1 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c -@@ -2032,7 +2032,7 @@ static bool hid_ignore(struct hid_device *hdev) +@@ -2033,7 +2033,7 @@ static bool hid_ignore(struct hid_device *hdev) int hid_add_device(struct hid_device *hdev) { @@ -33854,7 +33779,7 @@ index 279b863d..cf4afe1 100644 int ret; if (WARN_ON(hdev->status & HID_STAT_ADDED)) -@@ -2047,7 +2047,7 @@ int hid_add_device(struct hid_device *hdev) +@@ -2048,7 +2048,7 @@ int hid_add_device(struct hid_device *hdev) /* XXX hack, any other cleaner solution after the driver core * is converted to allow more than 20 bytes as the device name? */ dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus, @@ -36503,7 +36428,7 @@ index 68d1240..46b32eb 100644 {0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, {0, } diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c -index ee0d0b3..63f6b78 100644 +index d345215..b607565 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -64,7 +64,6 @@ enum omap_vout_channels { @@ -36514,7 +36439,7 @@ index ee0d0b3..63f6b78 100644 /* Variables configurable through module params*/ static u32 video1_numbuffers = 3; static u32 video2_numbuffers = 3; -@@ -999,6 +998,12 @@ static int omap_vout_open(struct file *file) +@@ -1001,6 +1000,12 @@ static int omap_vout_open(struct file *file) { struct videobuf_queue *q; struct omap_vout_device *vout = NULL; @@ -36527,7 +36452,7 @@ index ee0d0b3..63f6b78 100644 vout = video_drvdata(file); v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__); -@@ -1016,10 +1021,6 @@ static int omap_vout_open(struct file *file) +@@ -1018,10 +1023,6 @@ static int omap_vout_open(struct file *file) vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; q = &vout->vbq; @@ -41748,7 +41673,7 @@ index 57c01ab..8a05959 100644 /* diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c -index ae66278..b5f6c08 100644 +index be32b1b..b5f6c08 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -631,7 +631,7 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) @@ -41760,15 +41685,6 @@ index ae66278..b5f6c08 100644 { struct file *eventfp, *filep = NULL, *pollstart = NULL, *pollstop = NULL; -@@ -1073,7 +1073,7 @@ static int translate_desc(struct vhost_dev *dev, u64 addr, u32 len, - } - _iov = iov + ret; - size = reg->memory_size - addr + reg->guest_phys_addr; -- _iov->iov_len = min((u64)len, size); -+ _iov->iov_len = min((u64)len - s, size); - _iov->iov_base = (void __user *)(unsigned long) - (reg->userspace_addr + addr - reg->guest_phys_addr); - s += size; diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index b0b2ac3..89a4399 100644 --- a/drivers/video/aty/aty128fb.c @@ -41796,7 +41712,7 @@ index e132157..516db70 100644 return rc; diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c -index bf9a9b7..4ed1a97 100644 +index 9b8bcab..cc61f88 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -450,7 +450,7 @@ static int __init fb_console_setup(char *this_opt) @@ -41823,7 +41739,7 @@ index 5c3960d..15cf8fc 100644 goto out1; } diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c -index 7a41220..d202a9a 100644 +index c133dde..478888d 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -428,7 +428,7 @@ static void fb_do_show_logo(struct fb_info *info, struct fb_image *image, @@ -46162,10 +46078,10 @@ index 4fc4dbb..bae9dce 100644 __bio_for_each_segment(bvec, bio, i, 0) { char *addr = page_address(bvec->bv_page); diff --git a/fs/block_dev.c b/fs/block_dev.c -index 9b98987..fd211e3 100644 +index 613edd8..66ca5ea 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c -@@ -681,7 +681,7 @@ static bool bd_may_claim(struct block_device *bdev, struct block_device *whole, +@@ -682,7 +682,7 @@ static bool bd_may_claim(struct block_device *bdev, struct block_device *whole, else if (bdev->bd_contains == bdev) return true; /* is a whole device which isn't held */ @@ -46411,7 +46327,7 @@ index eccd339..4c1d995 100644 return 0; diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c -index 0e3c092..818480e 100644 +index b4d2438..0935840 100644 --- a/fs/cachefiles/rdwr.c +++ b/fs/cachefiles/rdwr.c @@ -945,7 +945,7 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page) @@ -47133,7 +47049,7 @@ index 451b9b8..12e5a03 100644 out_free_fd: diff --git a/fs/exec.c b/fs/exec.c -index c27fa0d..1b01ac5 100644 +index 312e297..4814b4e 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -55,12 +55,34 @@ @@ -48111,10 +48027,10 @@ index a203892..4e64db5 100644 } return 1; diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c -index d6970f7..5362903 100644 +index 484ffee..08d7602 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c -@@ -436,8 +436,8 @@ static int ext4_has_free_clusters(struct ext4_sb_info *sbi, +@@ -441,8 +441,8 @@ static int ext4_has_free_clusters(struct ext4_sb_info *sbi, /* Hm, nope. Are (enough) root reserved clusters available? */ if (sbi->s_resuid == current_fsuid() || ((sbi->s_resgid != 0) && in_group_p(sbi->s_resgid)) || @@ -48160,7 +48076,7 @@ index 8cb184c..09ff6c4 100644 /* locality groups */ diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c -index 1d07c12..9965aec 100644 +index 553ff71..f545238 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -1794,7 +1794,7 @@ void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac, @@ -50108,7 +50024,7 @@ index f6d411e..e82a08d 100644 next->d_inode->i_ino, dt_type(next->d_inode)) < 0) diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c -index 8392cb8..80d6193 100644 +index a3a0987..5e151c8 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c @@ -36,11 +36,11 @@ static const struct rpc_call_ops nlmclnt_cancel_ops; @@ -51104,7 +51020,7 @@ index d355e6e..578d905 100644 enum ocfs2_local_alloc_state diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c -index f169da4..9112253 100644 +index b7e74b5..19c6536 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c @@ -872,7 +872,7 @@ static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb, @@ -51116,7 +51032,7 @@ index f169da4..9112253 100644 /* You should never ask for this much metadata */ BUG_ON(bits_wanted > -@@ -2008,7 +2008,7 @@ int ocfs2_claim_metadata(handle_t *handle, +@@ -2007,7 +2007,7 @@ int ocfs2_claim_metadata(handle_t *handle, mlog_errno(status); goto bail; } @@ -51125,7 +51041,7 @@ index f169da4..9112253 100644 *suballoc_loc = res.sr_bg_blkno; *suballoc_bit_start = res.sr_bit_offset; -@@ -2172,7 +2172,7 @@ int ocfs2_claim_new_inode_at_loc(handle_t *handle, +@@ -2171,7 +2171,7 @@ int ocfs2_claim_new_inode_at_loc(handle_t *handle, trace_ocfs2_claim_new_inode_at_loc((unsigned long long)di_blkno, res->sr_bits); @@ -51134,7 +51050,7 @@ index f169da4..9112253 100644 BUG_ON(res->sr_bits != 1); -@@ -2214,7 +2214,7 @@ int ocfs2_claim_new_inode(handle_t *handle, +@@ -2213,7 +2213,7 @@ int ocfs2_claim_new_inode(handle_t *handle, mlog_errno(status); goto bail; } @@ -51143,7 +51059,7 @@ index f169da4..9112253 100644 BUG_ON(res.sr_bits != 1); -@@ -2318,7 +2318,7 @@ int __ocfs2_claim_clusters(handle_t *handle, +@@ -2317,7 +2317,7 @@ int __ocfs2_claim_clusters(handle_t *handle, cluster_start, num_clusters); if (!status) @@ -51152,7 +51068,7 @@ index f169da4..9112253 100644 } else { if (min_clusters > (osb->bitmap_cpg - 1)) { /* The only paths asking for contiguousness -@@ -2344,7 +2344,7 @@ int __ocfs2_claim_clusters(handle_t *handle, +@@ -2343,7 +2343,7 @@ int __ocfs2_claim_clusters(handle_t *handle, ocfs2_desc_bitmap_to_cluster_off(ac->ac_inode, res.sr_bg_blkno, res.sr_bit_offset); @@ -64287,7 +64203,7 @@ index 49a83ca..df96b54 100644 #undef __HANDLE_ITEM }; diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h -index f606406..9c3626e 100644 +index acd8d4b..44cf309 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -18,7 +18,7 @@ struct pt_regs; @@ -64307,7 +64223,7 @@ index f606406..9c3626e 100644 }; #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0 -@@ -88,6 +89,7 @@ struct linux_binfmt { +@@ -86,6 +87,7 @@ struct linux_binfmt { int (*load_binary)(struct linux_binprm *, struct pt_regs * regs); int (*load_shlib)(struct file *); int (*core_dump)(struct coredump_params *cprm); @@ -64877,7 +64793,7 @@ index 8eeb205..d59bfa2 100644 struct sock_filter insns[0]; }; diff --git a/include/linux/fs.h b/include/linux/fs.h -index 29b6353..b41fa04 100644 +index a276817..3355087 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1618,7 +1618,8 @@ struct file_operations { @@ -64890,7 +64806,7 @@ index 29b6353..b41fa04 100644 struct inode_operations { struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *); -@@ -2714,5 +2715,15 @@ static inline void inode_has_no_xattr(struct inode *inode) +@@ -2716,5 +2717,15 @@ static inline void inode_has_no_xattr(struct inode *inode) inode->i_flags |= S_NOSEC; } @@ -66389,7 +66305,7 @@ index c4d2fc1..5df9c19 100644 extern struct kgdb_arch arch_kgdb_ops; diff --git a/include/linux/kmod.h b/include/linux/kmod.h -index b16f653..eb908f4 100644 +index f8d4b27..269f55a 100644 --- a/include/linux/kmod.h +++ b/include/linux/kmod.h @@ -34,6 +34,8 @@ extern char modprobe_path[]; /* for sysctl */ @@ -66772,10 +66688,10 @@ index c5d5278..f0b68c8 100644 } diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h -index 1d1b1e1..2a13c78 100644 +index ee2baf0..e24a58c 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h -@@ -255,12 +255,12 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm) +@@ -256,12 +256,12 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm) */ #define ptep_clear_flush_notify(__vma, __address, __ptep) \ ({ \ @@ -70128,10 +70044,10 @@ index b463871..59495fd 100644 * nsown_capable - Check superior capability to one's own user_ns * @cap: The capability in question diff --git a/kernel/cgroup.c b/kernel/cgroup.c -index b6cacf1..811c188 100644 +index c0739f8..262bc6f 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c -@@ -5145,7 +5145,7 @@ static int cgroup_css_links_read(struct cgroup *cont, +@@ -5153,7 +5153,7 @@ static int cgroup_css_links_read(struct cgroup *cont, struct css_set *cg = link->cg; struct task_struct *task; int count = 0; @@ -71135,7 +71051,7 @@ index 9b22d03..6295b62 100644 prev->next = info->next; else diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c -index 6db7a5e..0d600bd 100644 +index cdd5607..c3fc919 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -1407,7 +1407,7 @@ void hrtimer_peek_ahead_timers(void) @@ -71320,10 +71236,29 @@ index dc7bc08..4601964 100644 /* Don't allow clients that don't understand the native diff --git a/kernel/kmod.c b/kernel/kmod.c -index a4bea97..7a1ae9a 100644 +index d6fe08a..ece0f1a 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c -@@ -73,13 +73,12 @@ char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe"; +@@ -64,7 +64,7 @@ static void free_modprobe_argv(struct subprocess_info *info) + kfree(info->argv); + } + +-static int call_modprobe(char *module_name, int wait) ++static int call_modprobe(char *module_name, char *module_param, int wait) + { + static char *envp[] = { + "HOME=/", +@@ -85,7 +85,8 @@ static int call_modprobe(char *module_name, int wait) + argv[1] = "-q"; + argv[2] = "--"; + argv[3] = module_name; /* check free_modprobe_argv() */ +- argv[4] = NULL; ++ argv[4] = module_param; ++ argv[5] = NULL; + + return call_usermodehelper_fns(modprobe_path, argv, envp, + wait | UMH_KILLABLE, NULL, free_modprobe_argv, NULL); +@@ -110,9 +111,8 @@ out: * If module auto-loading support is disabled then this function * becomes a no-operation. */ @@ -71334,12 +71269,7 @@ index a4bea97..7a1ae9a 100644 char module_name[MODULE_NAME_LEN]; unsigned int max_modprobes; int ret; -- char *argv[] = { modprobe_path, "-q", "--", module_name, NULL }; -+ char *argv[] = { modprobe_path, "-q", "--", module_name, module_param, NULL }; - static char *envp[] = { "HOME=/", - "TERM=linux", - "PATH=/sbin:/usr/sbin:/bin:/usr/bin", -@@ -88,9 +87,7 @@ int __request_module(bool wait, const char *fmt, ...) +@@ -120,9 +120,7 @@ int __request_module(bool wait, const char *fmt, ...) #define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */ static int kmod_loop_msg; @@ -71350,7 +71280,7 @@ index a4bea97..7a1ae9a 100644 if (ret >= MODULE_NAME_LEN) return -ENAMETOOLONG; -@@ -98,6 +95,20 @@ int __request_module(bool wait, const char *fmt, ...) +@@ -130,6 +128,20 @@ int __request_module(bool wait, const char *fmt, ...) if (ret) return ret; @@ -71371,7 +71301,13 @@ index a4bea97..7a1ae9a 100644 /* If modprobe needs a service that is in a module, we get a recursive * loop. Limit the number of running kmod threads to max_threads/2 or * MAX_KMOD_CONCURRENT, whichever is the smaller. A cleaner method -@@ -133,6 +144,47 @@ int __request_module(bool wait, const char *fmt, ...) +@@ -158,11 +170,52 @@ int __request_module(bool wait, const char *fmt, ...) + + trace_module_request(module_name, wait, _RET_IP_); + +- ret = call_modprobe(module_name, wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC); ++ ret = call_modprobe(module_name, module_param, wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC); + atomic_dec(&kmod_concurrent); return ret; } @@ -71419,7 +71355,7 @@ index a4bea97..7a1ae9a 100644 EXPORT_SYMBOL(__request_module); #endif /* CONFIG_MODULES */ -@@ -222,7 +274,7 @@ static int wait_for_helper(void *data) +@@ -265,7 +318,7 @@ static int wait_for_helper(void *data) * * Thus the __user pointer cast is valid here. */ @@ -72620,7 +72556,7 @@ index fa5f722..0c93e57 100644 { struct pid *pid; diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c -index e7cb76d..f396a93 100644 +index 962c291..31cf69d7 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -6,9 +6,11 @@ @@ -72644,7 +72580,7 @@ index e7cb76d..f396a93 100644 cleanup_timers(tsk->cpu_timers, tsk->utime, tsk->stime, tsk->se.sum_exec_runtime); -@@ -1606,14 +1610,14 @@ struct k_clock clock_posix_cpu = { +@@ -1625,14 +1629,14 @@ struct k_clock clock_posix_cpu = { static __init int init_posix_cpu_timers(void) { @@ -72662,7 +72598,7 @@ index e7cb76d..f396a93 100644 .clock_get = thread_cpu_clock_get, .timer_create = thread_cpu_timer_create, diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c -index 69185ae..cc2847a 100644 +index e885be1..380fe76 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -43,6 +43,7 @@ @@ -72745,7 +72681,7 @@ index 69185ae..cc2847a 100644 } static int common_timer_create(struct k_itimer *new_timer) -@@ -959,6 +960,13 @@ SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, +@@ -966,6 +967,13 @@ SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, if (copy_from_user(&new_tp, tp, sizeof (*tp))) return -EFAULT; @@ -74321,7 +74257,7 @@ index ea7ec7f..23d4094 100644 EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax); EXPORT_SYMBOL(register_sysctl_table); diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c -index a650694..d0c4f42 100644 +index 9f9aa32..d0c4f42 100644 --- a/kernel/sysctl_binary.c +++ b/kernel/sysctl_binary.c @@ -989,7 +989,7 @@ static ssize_t bin_intvec(struct file *file, @@ -74378,19 +74314,7 @@ index a650694..d0c4f42 100644 set_fs(old_fs); if (result < 0) goto out; -@@ -1194,9 +1194,10 @@ static ssize_t bin_dn_node_address(struct file *file, - - /* Convert the decnet address to binary */ - result = -EIO; -- nodep = strchr(buf, '.') + 1; -+ nodep = strchr(buf, '.'); - if (!nodep) - goto out; -+ ++nodep; - - area = simple_strtoul(buf, NULL, 10); - node = simple_strtoul(nodep, NULL, 10); -@@ -1233,7 +1234,7 @@ static ssize_t bin_dn_node_address(struct file *file, +@@ -1234,7 +1234,7 @@ static ssize_t bin_dn_node_address(struct file *file, le16_to_cpu(dnaddr) & 0x3ff); set_fs(KERNEL_DS); @@ -74673,7 +74597,7 @@ index 16fc34a..efd8bb8 100644 ret = -EIO; bt->dropped_file = debugfs_create_file("dropped", 0444, dir, bt, diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c -index 4b1a96b..1690055 100644 +index 6c880e8..1f2d08b 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1587,12 +1587,17 @@ ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec) @@ -74705,7 +74629,7 @@ index 4b1a96b..1690055 100644 { struct ftrace_func_probe *entry; struct ftrace_page *pg; -@@ -3968,8 +3973,6 @@ ftrace_enable_sysctl(struct ctl_table *table, int write, +@@ -3986,8 +3991,6 @@ ftrace_enable_sysctl(struct ctl_table *table, int write, #ifdef CONFIG_FUNCTION_GRAPH_TRACER static int ftrace_graph_active; @@ -74714,7 +74638,7 @@ index 4b1a96b..1690055 100644 int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace) { return 0; -@@ -4113,6 +4116,10 @@ ftrace_suspend_notifier_call(struct notifier_block *bl, unsigned long state, +@@ -4131,6 +4134,10 @@ ftrace_suspend_notifier_call(struct notifier_block *bl, unsigned long state, return NOTIFY_DONE; } @@ -74725,7 +74649,7 @@ index 4b1a96b..1690055 100644 int register_ftrace_graph(trace_func_graph_ret_t retfunc, trace_func_graph_ent_t entryfunc) { -@@ -4126,7 +4133,6 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc, +@@ -4144,7 +4151,6 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc, goto out; } @@ -75255,10 +75179,10 @@ index a8bc4d9..eae8357 100644 }; diff --git a/kernel/workqueue.c b/kernel/workqueue.c -index 7bf068a..1323074 100644 +index 0ad2420..64da53b 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c -@@ -3470,7 +3470,7 @@ static int __cpuinit trustee_thread(void *__gcwq) +@@ -3490,7 +3490,7 @@ static int __cpuinit trustee_thread(void *__gcwq) */ worker_flags |= WORKER_REBIND; worker_flags &= ~WORKER_ROGUE; @@ -78925,7 +78849,7 @@ index 50f0824..97710b4 100644 .next = NULL, }; diff --git a/mm/page_alloc.c b/mm/page_alloc.c -index 4d3a697..4f0e54f 100644 +index 5c028e2..4f0e54f 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -341,7 +341,7 @@ out: @@ -78986,52 +78910,6 @@ index 4d3a697..4f0e54f 100644 return 1; } return 0; -@@ -4253,10 +4271,11 @@ static void __meminit calculate_node_totalpages(struct pglist_data *pgdat, - * round what is now in bits to nearest long in bits, then return it in - * bytes. - */ --static unsigned long __init usemap_size(unsigned long zonesize) -+static unsigned long __init usemap_size(unsigned long zone_start_pfn, unsigned long zonesize) - { - unsigned long usemapsize; - -+ zonesize += zone_start_pfn & (pageblock_nr_pages-1); - usemapsize = roundup(zonesize, pageblock_nr_pages); - usemapsize = usemapsize >> pageblock_order; - usemapsize *= NR_PAGEBLOCK_BITS; -@@ -4266,17 +4285,19 @@ static unsigned long __init usemap_size(unsigned long zonesize) - } - - static void __init setup_usemap(struct pglist_data *pgdat, -- struct zone *zone, unsigned long zonesize) -+ struct zone *zone, -+ unsigned long zone_start_pfn, -+ unsigned long zonesize) - { -- unsigned long usemapsize = usemap_size(zonesize); -+ unsigned long usemapsize = usemap_size(zone_start_pfn, zonesize); - zone->pageblock_flags = NULL; - if (usemapsize) - zone->pageblock_flags = alloc_bootmem_node_nopanic(pgdat, - usemapsize); - } - #else --static inline void setup_usemap(struct pglist_data *pgdat, -- struct zone *zone, unsigned long zonesize) {} -+static inline void setup_usemap(struct pglist_data *pgdat, struct zone *zone, -+ unsigned long zone_start_pfn, unsigned long zonesize) {} - #endif /* CONFIG_SPARSEMEM */ - - #ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE -@@ -4401,7 +4422,7 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat, - continue; - - set_pageblock_order(); -- setup_usemap(pgdat, zone, size); -+ setup_usemap(pgdat, zone, zone_start_pfn, size); - ret = init_currently_empty_zone(zone, zone_start_pfn, - size, MEMMAP_EARLY); - BUG_ON(ret); diff --git a/mm/percpu.c b/mm/percpu.c index 5c29750..99f6386 100644 --- a/mm/percpu.c @@ -79212,7 +79090,7 @@ index 8685697..b490361 100644 struct anon_vma_chain *avc; struct anon_vma *anon_vma; diff --git a/mm/shmem.c b/mm/shmem.c -index 12b9e80..a31df98 100644 +index a78acf0..a31df98 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -31,7 +31,7 @@ @@ -79261,31 +79139,7 @@ index 12b9e80..a31df98 100644 if (size == 0) value = ""; /* empty EA, do not remove */ -@@ -2121,6 +2135,7 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data) - unsigned long inodes; - int error = -EINVAL; - -+ config.mpol = NULL; - if (shmem_parse_options(data, &config, true)) - return error; - -@@ -2145,8 +2160,13 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data) - sbinfo->max_inodes = config.max_inodes; - sbinfo->free_inodes = config.max_inodes - inodes; - -- mpol_put(sbinfo->mpol); -- sbinfo->mpol = config.mpol; /* transfers initial ref */ -+ /* -+ * Preserve previous mempolicy unless mpol remount option was specified. -+ */ -+ if (config.mpol) { -+ mpol_put(sbinfo->mpol); -+ sbinfo->mpol = config.mpol; /* transfers initial ref */ -+ } - out: - spin_unlock(&sbinfo->stat_lock); - return error; -@@ -2189,8 +2209,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) +@@ -2195,8 +2209,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) int err = -ENOMEM; /* Round up to L1_CACHE_BYTES to resist false sharing */ @@ -81756,6 +81610,18 @@ index 1e8a882..af175b4 100644 } EXPORT_SYMBOL(sock_init_data); +diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c +index 19acd00..dcb43f2 100644 +--- a/net/decnet/af_decnet.c ++++ b/net/decnet/af_decnet.c +@@ -469,6 +469,7 @@ static struct proto dn_proto = { + .sysctl_rmem = sysctl_decnet_rmem, + .max_header = DN_MAX_NSP_DATA_HEADER + 64, + .obj_size = sizeof(struct dn_sock), ++ .slab_flags = SLAB_USERCOPY, + }; + + static struct sock *dn_alloc_sock(struct net *net, struct socket *sock, gfp_t gfp) diff --git a/net/decnet/sysctl_net_decnet.c b/net/decnet/sysctl_net_decnet.c index 02e75d1..9a57a7c 100644 --- a/net/decnet/sysctl_net_decnet.c @@ -82179,7 +82045,7 @@ index 24e556e..f6918b4 100644 case IPT_SO_GET_ENTRIES: diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c -index 43d4c3b..1914409 100644 +index 294a380..885a292 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -836,7 +836,7 @@ static void ping_format_sock(struct sock *sp, struct seq_file *f, @@ -83158,6 +83024,24 @@ index 253695d..9481ce8 100644 seq_printf(m, "Max data size: %d\n", self->max_data_size); seq_printf(m, "Max header size: %d\n", self->max_header_size); +diff --git a/net/irda/iriap.c b/net/irda/iriap.c +index e71e85b..29340a9 100644 +--- a/net/irda/iriap.c ++++ b/net/irda/iriap.c +@@ -495,8 +495,11 @@ static void iriap_getvaluebyclass_confirm(struct iriap_cb *self, + /* case CS_ISO_8859_9: */ + /* case CS_UNICODE: */ + default: +- IRDA_DEBUG(0, "%s(), charset %s, not supported\n", +- __func__, ias_charset_types[charset]); ++ IRDA_DEBUG(0, "%s(), charset [%d] %s, not supported\n", ++ __func__, charset, ++ charset < ARRAY_SIZE(ias_charset_types) ? ++ ias_charset_types[charset] : ++ "(unknown)"); + + /* Aborting, close connection! */ + iriap_disconnect_request(self); diff --git a/net/irda/irttp.c b/net/irda/irttp.c index 32e3bb0..a4e5eb8 100644 --- a/net/irda/irttp.c @@ -83254,6 +83138,18 @@ index 93a41a0..d4b4edb 100644 NLA_PUT_U32(skb, L2TP_ATTR_CONN_ID, tunnel->tunnel_id); NLA_PUT_U32(skb, L2TP_ATTR_SESSION_ID, session->session_id); +diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c +index b1bd16f..6f60175 100644 +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -360,6 +360,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh + l2tp_xmit_skb(session, skb, session->hdr_len); + + sock_put(ps->tunnel_sock); ++ sock_put(sk); + + return error; + diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 73495f1..ad51356 100644 --- a/net/mac80211/ieee80211_i.h @@ -84053,6 +83949,20 @@ index 5e57347..3916042 100644 } #endif +diff --git a/net/rds/message.c b/net/rds/message.c +index f0a4658..aff589c 100644 +--- a/net/rds/message.c ++++ b/net/rds/message.c +@@ -197,6 +197,9 @@ struct rds_message *rds_message_alloc(unsigned int extra_len, gfp_t gfp) + { + struct rds_message *rm; + ++ if (extra_len > KMALLOC_MAX_SIZE - sizeof(struct rds_message)) ++ return NULL; ++ + rm = kzalloc(sizeof(struct rds_message) + extra_len, gfp); + if (!rm) + goto out; diff --git a/net/rds/tcp.c b/net/rds/tcp.c index edac9ef..16bcb98 100644 --- a/net/rds/tcp.c @@ -84440,6 +84350,46 @@ index 5e0d86e..8633998 100644 if (copy_to_user(to, &temp, addrlen)) return -EFAULT; to += addrlen; +diff --git a/net/sctp/ssnmap.c b/net/sctp/ssnmap.c +index 442ad4e..825ea94 100644 +--- a/net/sctp/ssnmap.c ++++ b/net/sctp/ssnmap.c +@@ -41,8 +41,6 @@ + #include <net/sctp/sctp.h> + #include <net/sctp/sm.h> + +-#define MAX_KMALLOC_SIZE 131072 +- + static struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in, + __u16 out); + +@@ -65,7 +63,7 @@ struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, + int size; + + size = sctp_ssnmap_size(in, out); +- if (size <= MAX_KMALLOC_SIZE) ++ if (size <= KMALLOC_MAX_SIZE) + retval = kmalloc(size, gfp); + else + retval = (struct sctp_ssnmap *) +@@ -82,7 +80,7 @@ struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, + return retval; + + fail_map: +- if (size <= MAX_KMALLOC_SIZE) ++ if (size <= KMALLOC_MAX_SIZE) + kfree(retval); + else + free_pages((unsigned long)retval, get_order(size)); +@@ -124,7 +122,7 @@ void sctp_ssnmap_free(struct sctp_ssnmap *map) + int size; + + size = sctp_ssnmap_size(map->in.len, map->out.len); +- if (size <= MAX_KMALLOC_SIZE) ++ if (size <= KMALLOC_MAX_SIZE) + kfree(map); + else + free_pages((unsigned long)map, get_order(size)); diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 8da4481..d02565e 100644 --- a/net/sctp/transport.c @@ -86838,6 +86788,19 @@ index 37a7f3b..86dc19f 100644 goto error; buflen -= tmp; +diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c +index 1068cb1..60d0df7 100644 +--- a/security/keys/process_keys.c ++++ b/security/keys/process_keys.c +@@ -54,7 +54,7 @@ int install_user_keyrings(void) + + kenter("%p{%u}", user, user->uid); + +- if (user->uid_keyring) { ++ if (user->uid_keyring && user->session_keyring) { + kleave(" = 0 [exist]"); + return 0; + } diff --git a/security/lsm_audit.c b/security/lsm_audit.c index 893af8a..ba9237c 100644 --- a/security/lsm_audit.c diff --git a/3.2.39/4425_grsec_remove_EI_PAX.patch b/3.2.40/4425_grsec_remove_EI_PAX.patch index 97e6951..97e6951 100644 --- a/3.2.39/4425_grsec_remove_EI_PAX.patch +++ b/3.2.40/4425_grsec_remove_EI_PAX.patch diff --git a/3.2.39/4430_grsec-remove-localversion-grsec.patch b/3.2.40/4430_grsec-remove-localversion-grsec.patch index 31cf878..31cf878 100644 --- a/3.2.39/4430_grsec-remove-localversion-grsec.patch +++ b/3.2.40/4430_grsec-remove-localversion-grsec.patch diff --git a/3.2.39/4435_grsec-mute-warnings.patch b/3.2.40/4435_grsec-mute-warnings.patch index e85abd6..e85abd6 100644 --- a/3.2.39/4435_grsec-mute-warnings.patch +++ b/3.2.40/4435_grsec-mute-warnings.patch diff --git a/3.2.39/4440_grsec-remove-protected-paths.patch b/3.2.40/4440_grsec-remove-protected-paths.patch index 637934a..637934a 100644 --- a/3.2.39/4440_grsec-remove-protected-paths.patch +++ b/3.2.40/4440_grsec-remove-protected-paths.patch diff --git a/3.2.39/4450_grsec-kconfig-default-gids.patch b/3.2.40/4450_grsec-kconfig-default-gids.patch index 3dfdc8f..3dfdc8f 100644 --- a/3.2.39/4450_grsec-kconfig-default-gids.patch +++ b/3.2.40/4450_grsec-kconfig-default-gids.patch diff --git a/3.2.39/4465_selinux-avc_audit-log-curr_ip.patch b/3.2.40/4465_selinux-avc_audit-log-curr_ip.patch index a7cc9cd..a7cc9cd 100644 --- a/3.2.39/4465_selinux-avc_audit-log-curr_ip.patch +++ b/3.2.40/4465_selinux-avc_audit-log-curr_ip.patch diff --git a/3.2.39/4470_disable-compat_vdso.patch b/3.2.40/4470_disable-compat_vdso.patch index c06bd8b..c06bd8b 100644 --- a/3.2.39/4470_disable-compat_vdso.patch +++ b/3.2.40/4470_disable-compat_vdso.patch diff --git a/3.8.2/0000_README b/3.8.2/0000_README index 4525042..ff4a56d 100644 --- a/3.8.2/0000_README +++ b/3.8.2/0000_README @@ -6,7 +6,7 @@ Patch: 1001_linux-3.8.1.patch From: http://www.kernel.org Desc: Linux 3.8.1 -Patch: 4420_grsecurity-2.9.1-3.8.2-201303041742.patch +Patch: 4420_grsecurity-2.9.1-3.8.2-201303082215.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.8.2/4420_grsecurity-2.9.1-3.8.2-201303041742.patch b/3.8.2/4420_grsecurity-2.9.1-3.8.2-201303082215.patch index c57c85d..6e0e897 100644 --- a/3.8.2/4420_grsecurity-2.9.1-3.8.2-201303041742.patch +++ b/3.8.2/4420_grsecurity-2.9.1-3.8.2-201303082215.patch @@ -1,5 +1,5 @@ diff --git a/Documentation/dontdiff b/Documentation/dontdiff -index b89a739..dba90c5 100644 +index b89a739..b47493f 100644 --- a/Documentation/dontdiff +++ b/Documentation/dontdiff @@ -2,9 +2,11 @@ @@ -172,10 +172,11 @@ index b89a739..dba90c5 100644 relocs rlim_names.h rn50_reg_safe.h -@@ -213,8 +238,11 @@ series +@@ -213,8 +238,12 @@ series setup setup.bin setup.elf ++signing_key* +size_overflow_hash.h sImage +slabinfo @@ -184,7 +185,7 @@ index b89a739..dba90c5 100644 split-include syscalltab.h tables.c -@@ -224,6 +252,7 @@ tftpboot.img +@@ -224,6 +253,7 @@ tftpboot.img timeconst.h times.h* trix_boot.h @@ -192,7 +193,7 @@ index b89a739..dba90c5 100644 utsrelease.h* vdso-syms.lds vdso.lds -@@ -235,13 +264,17 @@ vdso32.lds +@@ -235,13 +265,17 @@ vdso32.lds vdso32.so.dbg vdso64.lds vdso64.so.dbg @@ -210,7 +211,7 @@ index b89a739..dba90c5 100644 vmlinuz voffset.h vsyscall.lds -@@ -249,9 +282,11 @@ vsyscall_32.lds +@@ -249,9 +283,12 @@ vsyscall_32.lds wanxlfw.inc uImage unifdef @@ -218,6 +219,7 @@ index b89a739..dba90c5 100644 wakeup.bin wakeup.elf wakeup.lds ++x509* zImage* zconf.hash.c +zconf.lex.c @@ -252,7 +254,7 @@ index 986614d..0afd461 100644 pcd. [PARIDE] diff --git a/Makefile b/Makefile -index 20d5318..19c7540 100644 +index 20d5318..d5cec9c 100644 --- a/Makefile +++ b/Makefile @@ -241,8 +241,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ @@ -278,7 +280,7 @@ index 20d5318..19c7540 100644 $(Q)$(MAKE) $(build)=scripts/basic $(Q)rm -f .tmp_quiet_recordmcount -@@ -575,6 +576,64 @@ else +@@ -575,6 +576,62 @@ else KBUILD_CFLAGS += -O2 endif @@ -289,11 +291,9 @@ index 20d5318..19c7540 100644 +PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh "$(HOSTCC)" "$(HOSTCXX)" "$(CC)") +endif +ifneq ($(PLUGINCC),) -+ifndef DISABLE_PAX_CONSTIFY_PLUGIN +ifndef CONFIG_UML +CONSTIFY_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/constify_plugin.so -DCONSTIFY_PLUGIN +endif -+endif +ifdef CONFIG_PAX_MEMORY_STACKLEAK +STACKLEAK_PLUGIN_CFLAGS := -fplugin=$(objtree)/tools/gcc/stackleak_plugin.so -DSTACKLEAK_PLUGIN +STACKLEAK_PLUGIN_CFLAGS += -fplugin-arg-stackleak_plugin-track-lowest-sp=100 @@ -343,7 +343,7 @@ index 20d5318..19c7540 100644 include $(srctree)/arch/$(SRCARCH)/Makefile ifdef CONFIG_READABLE_ASM -@@ -731,7 +790,7 @@ export mod_sign_cmd +@@ -731,7 +788,7 @@ export mod_sign_cmd ifeq ($(KBUILD_EXTMOD),) @@ -352,7 +352,7 @@ index 20d5318..19c7540 100644 vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \ $(core-y) $(core-m) $(drivers-y) $(drivers-m) \ -@@ -778,6 +837,8 @@ endif +@@ -778,6 +835,8 @@ endif # The actual objects are generated when descending, # make sure no implicit rule kicks in @@ -361,7 +361,7 @@ index 20d5318..19c7540 100644 $(sort $(vmlinux-deps)): $(vmlinux-dirs) ; # Handle descending into subdirectories listed in $(vmlinux-dirs) -@@ -787,7 +848,7 @@ $(sort $(vmlinux-deps)): $(vmlinux-dirs) ; +@@ -787,7 +846,7 @@ $(sort $(vmlinux-deps)): $(vmlinux-dirs) ; # Error messages still appears in the original language PHONY += $(vmlinux-dirs) @@ -370,7 +370,7 @@ index 20d5318..19c7540 100644 $(Q)$(MAKE) $(build)=$@ # Store (new) KERNELRELASE string in include/config/kernel.release -@@ -831,6 +892,7 @@ prepare0: archprepare FORCE +@@ -831,6 +890,7 @@ prepare0: archprepare FORCE $(Q)$(MAKE) $(build)=. # All the preparing.. @@ -378,7 +378,7 @@ index 20d5318..19c7540 100644 prepare: prepare0 # Generate some files -@@ -938,6 +1000,8 @@ all: modules +@@ -938,6 +998,8 @@ all: modules # using awk while concatenating to the final file. PHONY += modules @@ -387,7 +387,7 @@ index 20d5318..19c7540 100644 modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules.builtin $(Q)$(AWK) '!x[$$0]++' $(vmlinux-dirs:%=$(objtree)/%/modules.order) > $(objtree)/modules.order @$(kecho) ' Building modules, stage 2.'; -@@ -953,7 +1017,7 @@ modules.builtin: $(vmlinux-dirs:%=%/modules.builtin) +@@ -953,7 +1015,7 @@ modules.builtin: $(vmlinux-dirs:%=%/modules.builtin) # Target to prepare building external modules PHONY += modules_prepare @@ -396,7 +396,7 @@ index 20d5318..19c7540 100644 # Target to install modules PHONY += modules_install -@@ -1019,7 +1083,7 @@ MRPROPER_FILES += .config .config.old .version .old_version $(version_h) \ +@@ -1019,7 +1081,7 @@ MRPROPER_FILES += .config .config.old .version .old_version $(version_h) \ Module.symvers tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS \ signing_key.priv signing_key.x509 x509.genkey \ extra_certificates signing_key.x509.keyid \ @@ -405,7 +405,7 @@ index 20d5318..19c7540 100644 # clean - Delete most, but leave enough to build external modules # -@@ -1059,6 +1123,7 @@ distclean: mrproper +@@ -1059,6 +1121,7 @@ distclean: mrproper \( -name '*.orig' -o -name '*.rej' -o -name '*~' \ -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \ -o -name '.*.rej' \ @@ -413,7 +413,7 @@ index 20d5318..19c7540 100644 -o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \ -type f -print | xargs rm -f -@@ -1219,6 +1284,8 @@ PHONY += $(module-dirs) modules +@@ -1219,6 +1282,8 @@ PHONY += $(module-dirs) modules $(module-dirs): crmodverdir $(objtree)/Module.symvers $(Q)$(MAKE) $(build)=$(patsubst _module_%,%,$@) @@ -422,7 +422,7 @@ index 20d5318..19c7540 100644 modules: $(module-dirs) @$(kecho) ' Building modules, stage 2.'; $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost -@@ -1355,17 +1422,21 @@ else +@@ -1355,17 +1420,21 @@ else target-dir = $(if $(KBUILD_EXTMOD),$(dir $<),$(dir $@)) endif @@ -448,7 +448,7 @@ index 20d5318..19c7540 100644 $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) %.symtypes: %.c prepare scripts FORCE $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) -@@ -1375,11 +1446,15 @@ endif +@@ -1375,11 +1444,15 @@ endif $(cmd_crmodverdir) $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ $(build)=$(build-dir) @@ -810,6 +810,28 @@ index 67874b8..0e40765 100644 default y if CPU_FEROCEON help Implement faster copy_to_user and clear_user methods for CPU +diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c +index 87dfa902..3a523fc 100644 +--- a/arch/arm/common/gic.c ++++ b/arch/arm/common/gic.c +@@ -81,7 +81,7 @@ static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly; + * Supported arch specific GIC irq extension. + * Default make them NULL. + */ +-struct irq_chip gic_arch_extn = { ++irq_chip_no_const gic_arch_extn __read_only = { + .irq_eoi = NULL, + .irq_mask = NULL, + .irq_unmask = NULL, +@@ -329,7 +329,7 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) + chained_irq_exit(chip, desc); + } + +-static struct irq_chip gic_chip = { ++static irq_chip_no_const gic_chip __read_only = { + .name = "GIC", + .irq_mask = gic_mask_irq, + .irq_unmask = gic_unmask_irq, diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h index c79f61f..9ac0642 100644 --- a/arch/arm/include/asm/atomic.h @@ -1540,7 +1562,7 @@ index ab98fdd..6b19938 100644 #define udelay(n) \ (__builtin_constant_p(n) ? \ diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h -index 6ddbe44..758b5f2 100644 +index 6ddbe44..b5e38b1 100644 --- a/arch/arm/include/asm/domain.h +++ b/arch/arm/include/asm/domain.h @@ -48,18 +48,37 @@ @@ -1552,7 +1574,7 @@ index 6ddbe44..758b5f2 100644 +#define DOMAIN_USERCLIENT 1 +#define DOMAIN_KERNELCLIENT 1 #define DOMAIN_MANAGER 3 -+#define DOMAIN_VECTORS DOMAIN_USER ++#define DOMAIN_VECTORS DOMAIN_USER #else + +#ifdef CONFIG_PAX_KERNEXEC @@ -1699,6 +1721,22 @@ index e42cf59..7b94b8f 100644 pagefault_enable(); /* subsumes preempt_enable() */ if (!ret) { +diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h +index 4b1ce6c..bea3f73 100644 +--- a/arch/arm/include/asm/hardware/gic.h ++++ b/arch/arm/include/asm/hardware/gic.h +@@ -34,9 +34,10 @@ + + #ifndef __ASSEMBLY__ + #include <linux/irqdomain.h> ++#include <linux/irq.h> + struct device_node; + +-extern struct irq_chip gic_arch_extn; ++extern irq_chip_no_const gic_arch_extn; + + void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *, + u32 offset, struct device_node *); diff --git a/arch/arm/include/asm/kmap_types.h b/arch/arm/include/asm/kmap_types.h index 83eb2f7..ed77159 100644 --- a/arch/arm/include/asm/kmap_types.h @@ -13099,6 +13137,19 @@ index eb92a6e..b98b2f4 100644 /* EISA */ extern void eisa_set_level_irq(unsigned int irq); +diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h +index a203659..9889f1c 100644 +--- a/arch/x86/include/asm/i8259.h ++++ b/arch/x86/include/asm/i8259.h +@@ -62,7 +62,7 @@ struct legacy_pic { + void (*init)(int auto_eoi); + int (*irq_pending)(unsigned int irq); + void (*make_irq)(unsigned int irq); +-}; ++} __do_const; + + extern struct legacy_pic *legacy_pic; + extern struct legacy_pic null_legacy_pic; diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index d8e8eef..15b1179 100644 --- a/arch/x86/include/asm/io.h @@ -13598,6 +13649,33 @@ index e3b7819..b257c64 100644 +#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_PAX_KERNEXEC MODULE_PAX_UDEREF + #endif /* _ASM_X86_MODULE_H */ +diff --git a/arch/x86/include/asm/nmi.h b/arch/x86/include/asm/nmi.h +index c0fa356..07a498a 100644 +--- a/arch/x86/include/asm/nmi.h ++++ b/arch/x86/include/asm/nmi.h +@@ -42,11 +42,11 @@ struct nmiaction { + nmi_handler_t handler; + unsigned long flags; + const char *name; +-}; ++} __do_const; + + #define register_nmi_handler(t, fn, fg, n, init...) \ + ({ \ +- static struct nmiaction init fn##_na = { \ ++ static const struct nmiaction init fn##_na = { \ + .handler = (fn), \ + .name = (n), \ + .flags = (fg), \ +@@ -54,7 +54,7 @@ struct nmiaction { + __register_nmi_handler((t), &fn##_na); \ + }) + +-int __register_nmi_handler(unsigned int, struct nmiaction *); ++int __register_nmi_handler(unsigned int, const struct nmiaction *); + + void unregister_nmi_handler(unsigned int, const char *); + diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h index 320f7bb..e89f8f8 100644 --- a/arch/x86/include/asm/page_64_types.h @@ -16055,6 +16133,28 @@ index 34e923a..0c6bb6e 100644 obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o obj-y += syscall_$(BITS).o obj-$(CONFIG_X86_64) += vsyscall_64.o +diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c +index bacf4b0..4ede72e 100644 +--- a/arch/x86/kernel/acpi/boot.c ++++ b/arch/x86/kernel/acpi/boot.c +@@ -1358,7 +1358,7 @@ static int __init dmi_ignore_irq0_timer_override(const struct dmi_system_id *d) + * If your system is blacklisted here, but you find that acpi=force + * works for you, please contact linux-acpi@vger.kernel.org + */ +-static struct dmi_system_id __initdata acpi_dmi_table[] = { ++static const struct dmi_system_id __initconst acpi_dmi_table[] = { + /* + * Boxes that need ACPI disabled + */ +@@ -1433,7 +1433,7 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = { + }; + + /* second table for DMI checks that should run after early-quirks */ +-static struct dmi_system_id __initdata acpi_dmi_table_late[] = { ++static const struct dmi_system_id __initconst acpi_dmi_table_late[] = { + /* + * HP laptops which use a DSDT reporting as HP/SB400/10000, + * which includes some code which overrides all temperature diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index d5e0d71..6533e08 100644 --- a/arch/x86/kernel/acpi/sleep.c @@ -16273,6 +16373,19 @@ index 00c77cf..2dc6a2d 100644 .name = "physical flat", .probe = physflat_probe, +diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c +index e145f28..2752888 100644 +--- a/arch/x86/kernel/apic/apic_noop.c ++++ b/arch/x86/kernel/apic/apic_noop.c +@@ -119,7 +119,7 @@ static void noop_apic_write(u32 reg, u32 v) + WARN_ON_ONCE(cpu_has_apic && !disable_apic); + } + +-struct apic apic_noop = { ++struct apic apic_noop __read_only = { + .name = "noop", + .probe = noop_probe, + .acpi_madt_oem_check = NULL, diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c index d50e364..543bee3 100644 --- a/arch/x86/kernel/apic/bigsmp_32.c @@ -16287,7 +16400,7 @@ index d50e364..543bee3 100644 .name = "bigsmp", .probe = probe_bigsmp, diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c -index 0874799..24a836e 100644 +index 0874799..a7a7892 100644 --- a/arch/x86/kernel/apic/es7000_32.c +++ b/arch/x86/kernel/apic/es7000_32.c @@ -608,8 +608,7 @@ static int es7000_mps_oem_check_cluster(struct mpc_table *mpc, char *oem, @@ -16305,12 +16418,12 @@ index 0874799..24a836e 100644 }; -static struct apic __refdata apic_es7000 = { -+static struct apic __refdata apic_es7000 __read_only = { ++static struct apic apic_es7000 __read_only = { .name = "es7000", .probe = probe_es7000, diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c -index b739d39..6e4f1db 100644 +index b739d39..aebc14c 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1084,7 +1084,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin, @@ -16349,6 +16462,24 @@ index b739d39..6e4f1db 100644 eoi_ioapic_irq(irq, cfg); } +@@ -2567,11 +2567,13 @@ static void ir_print_prefix(struct irq_data *data, struct seq_file *p) + + static void irq_remap_modify_chip_defaults(struct irq_chip *chip) + { +- chip->irq_print_chip = ir_print_prefix; +- chip->irq_ack = ir_ack_apic_edge; +- chip->irq_eoi = ir_ack_apic_level; ++ pax_open_kernel(); ++ *(void **)&chip->irq_print_chip = ir_print_prefix; ++ *(void **)&chip->irq_ack = ir_ack_apic_edge; ++ *(void **)&chip->irq_eoi = ir_ack_apic_level; + +- chip->irq_set_affinity = set_remapped_irq_affinity; ++ *(void **)&chip->irq_set_affinity = set_remapped_irq_affinity; ++ pax_close_kernel(); + } + #endif /* CONFIG_IRQ_REMAP */ + diff --git a/arch/x86/kernel/apic/numaq_32.c b/arch/x86/kernel/apic/numaq_32.c index d661ee9..791fd33 100644 --- a/arch/x86/kernel/apic/numaq_32.c @@ -16850,7 +16981,7 @@ index 84c1309..39b7224 100644 }; diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c -index 80dbda8..b45ebad 100644 +index 80dbda8..be16652 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -45,6 +45,7 @@ @@ -16974,6 +17105,15 @@ index 80dbda8..b45ebad 100644 .notifier_call = mce_cpu_callback, }; +@@ -2382,7 +2385,7 @@ static __init void mce_init_banks(void) + + for (i = 0; i < mca_cfg.banks; i++) { + struct mce_bank *b = &mce_banks[i]; +- struct device_attribute *a = &b->attr; ++ device_attribute_no_const *a = &b->attr; + + sysfs_attr_init(&a->attr); + a->attr.name = b->attrname; @@ -2450,7 +2453,7 @@ struct dentry *mce_get_debugfs_dir(void) static void mce_reset(void) { @@ -17067,9 +17207,36 @@ index df5e41f..816c719 100644 extern int generic_get_free_region(unsigned long base, unsigned long size, int replace_reg); diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c -index 6774c17..a691911 100644 +index 6774c17..72c1b22 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c +@@ -1305,7 +1305,7 @@ static void __init pmu_check_apic(void) + pr_info("no hardware sampling interrupt available.\n"); + } + +-static struct attribute_group x86_pmu_format_group = { ++static attribute_group_no_const x86_pmu_format_group = { + .name = "format", + .attrs = NULL, + }; +@@ -1313,7 +1313,7 @@ static struct attribute_group x86_pmu_format_group = { + struct perf_pmu_events_attr { + struct device_attribute attr; + u64 id; +-}; ++} __do_const; + + /* + * Remove all undefined events (x86_pmu.event_map(id) == 0) +@@ -1381,7 +1381,7 @@ static struct attribute *events_attr[] = { + NULL, + }; + +-static struct attribute_group x86_pmu_events_group = { ++static attribute_group_no_const x86_pmu_events_group = { + .name = "events", + .attrs = events_attr, + }; @@ -1880,7 +1880,7 @@ static unsigned long get_segment_base(unsigned int segment) if (idx > GDT_ENTRIES) return 0; @@ -17107,9 +17274,18 @@ index 4914e94..60b06e3 100644 intel_ds_init(); diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c -index b43200d..62cddfe 100644 +index b43200d..7fdcdbb 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c +@@ -2428,7 +2428,7 @@ static void __init uncore_types_exit(struct intel_uncore_type **types) + static int __init uncore_type_init(struct intel_uncore_type *type) + { + struct intel_uncore_pmu *pmus; +- struct attribute_group *events_group; ++ attribute_group_no_const *events_group; + struct attribute **attrs; + int i, j; + @@ -2826,7 +2826,7 @@ static int return NOTIFY_OK; } @@ -17119,6 +17295,19 @@ index b43200d..62cddfe 100644 .notifier_call = uncore_cpu_notifier, /* * to migrate uncore events, our notifier should be executed +diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h +index e68a455..975a932 100644 +--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h ++++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h +@@ -428,7 +428,7 @@ struct intel_uncore_box { + struct uncore_event_desc { + struct kobj_attribute attr; + const char *config; +-}; ++} __do_const; + + #define INTEL_UNCORE_EVENT_DESC(_name, _config) \ + { \ diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c index 60c7891..9e911d3 100644 --- a/arch/x86/kernel/cpuid.c @@ -20191,7 +20380,7 @@ index 245a71d..89d9ce4 100644 /* diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c -index 9a5c460..dc4374d 100644 +index 9a5c460..b332a4b 100644 --- a/arch/x86/kernel/i8259.c +++ b/arch/x86/kernel/i8259.c @@ -209,7 +209,7 @@ spurious_8259A_irq: @@ -20203,6 +20392,38 @@ index 9a5c460..dc4374d 100644 /* * Theoretically we do not have to handle this IRQ, * but in Linux this does not cause problems and is +@@ -333,14 +333,16 @@ static void init_8259A(int auto_eoi) + /* (slave's support for AEOI in flat mode is to be investigated) */ + outb_pic(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR); + ++ pax_open_kernel(); + if (auto_eoi) + /* + * In AEOI mode we just have to mask the interrupt + * when acking. + */ +- i8259A_chip.irq_mask_ack = disable_8259A_irq; ++ *(void **)&i8259A_chip.irq_mask_ack = disable_8259A_irq; + else +- i8259A_chip.irq_mask_ack = mask_and_ack_8259A; ++ *(void **)&i8259A_chip.irq_mask_ack = mask_and_ack_8259A; ++ pax_close_kernel(); + + udelay(100); /* wait for 8259A to initialize */ + +diff --git a/arch/x86/kernel/io_delay.c b/arch/x86/kernel/io_delay.c +index a979b5b..1d6db75 100644 +--- a/arch/x86/kernel/io_delay.c ++++ b/arch/x86/kernel/io_delay.c +@@ -58,7 +58,7 @@ static int __init dmi_io_delay_0xed_port(const struct dmi_system_id *id) + * Quirk table for systems that misbehave (lock up, etc.) if port + * 0x80 is used: + */ +-static struct dmi_system_id __initdata io_delay_0xed_port_dmi_table[] = { ++static const struct dmi_system_id __initconst io_delay_0xed_port_dmi_table[] = { + { + .callback = dmi_io_delay_0xed_port, + .ident = "Compaq Presario V6000", diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c index 8c96897..be66bfa 100644 --- a/arch/x86/kernel/ioport.c @@ -21021,9 +21242,39 @@ index 4929502..686c291 100644 }; diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c -index f84f5c5..e27e54b 100644 +index f84f5c5..f404e81 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c +@@ -105,7 +105,7 @@ static int __kprobes nmi_handle(unsigned int type, struct pt_regs *regs, bool b2 + return handled; + } + +-int __register_nmi_handler(unsigned int type, struct nmiaction *action) ++int __register_nmi_handler(unsigned int type, const struct nmiaction *action) + { + struct nmi_desc *desc = nmi_to_desc(type); + unsigned long flags; +@@ -129,9 +129,9 @@ int __register_nmi_handler(unsigned int type, struct nmiaction *action) + * event confuses some handlers (kdump uses this flag) + */ + if (action->flags & NMI_FLAG_FIRST) +- list_add_rcu(&action->list, &desc->head); ++ pax_list_add_rcu((struct list_head *)&action->list, &desc->head); + else +- list_add_tail_rcu(&action->list, &desc->head); ++ pax_list_add_tail_rcu((struct list_head *)&action->list, &desc->head); + + spin_unlock_irqrestore(&desc->lock, flags); + return 0; +@@ -154,7 +154,7 @@ void unregister_nmi_handler(unsigned int type, const char *name) + if (!strcmp(n->name, name)) { + WARN(in_nmi(), + "Trying to free NMI (%s) from NMI context!\n", n->name); +- list_del_rcu(&n->list); ++ pax_list_del_rcu((struct list_head *)&n->list); + break; + } + } @@ -479,6 +479,17 @@ static inline void nmi_nesting_postprocess(void) dotraplinkage notrace __kprobes void do_nmi(struct pt_regs *regs, long error_code) @@ -21042,6 +21293,28 @@ index f84f5c5..e27e54b 100644 nmi_nesting_preprocess(regs); nmi_enter(); +diff --git a/arch/x86/kernel/nmi_selftest.c b/arch/x86/kernel/nmi_selftest.c +index 6d9582e..f746287 100644 +--- a/arch/x86/kernel/nmi_selftest.c ++++ b/arch/x86/kernel/nmi_selftest.c +@@ -43,7 +43,7 @@ static void __init init_nmi_testsuite(void) + { + /* trap all the unknown NMIs we may generate */ + register_nmi_handler(NMI_UNKNOWN, nmi_unk_cb, 0, "nmi_selftest_unk", +- __initdata); ++ __initconst); + } + + static void __init cleanup_nmi_testsuite(void) +@@ -66,7 +66,7 @@ static void __init test_nmi_ipi(struct cpumask *mask) + unsigned long timeout; + + if (register_nmi_handler(NMI_LOCAL, test_nmi_ipi_callback, +- NMI_FLAG_FIRST, "nmi_selftest", __initdata)) { ++ NMI_FLAG_FIRST, "nmi_selftest", __initconst)) { + nmi_fail = FAILURE; + return; + } diff --git a/arch/x86/kernel/paravirt-spinlocks.c b/arch/x86/kernel/paravirt-spinlocks.c index 676b8c7..870ba04 100644 --- a/arch/x86/kernel/paravirt-spinlocks.c @@ -21203,6 +21476,19 @@ index 35ccf75..7a15747 100644 #define DEBUG 1 +diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c +index 6c483ba..d10ce2f 100644 +--- a/arch/x86/kernel/pci-swiotlb.c ++++ b/arch/x86/kernel/pci-swiotlb.c +@@ -32,7 +32,7 @@ static void x86_swiotlb_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_addr, + struct dma_attrs *attrs) + { +- swiotlb_free_coherent(dev, size, vaddr, dma_addr); ++ swiotlb_free_coherent(dev, size, vaddr, dma_addr, attrs); + } + + static struct dma_map_ops swiotlb_dma_ops = { diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 2ed787f..f70c9f6 100644 --- a/arch/x86/kernel/process.c @@ -29017,6 +29303,89 @@ index d6aa6e8..266395a 100644 unsigned long stack = kernel_stack_pointer(regs); if (depth) dump_trace(NULL, regs, (unsigned long *)stack, 0, +diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c +index 48768df..ba9143c 100644 +--- a/arch/x86/oprofile/nmi_int.c ++++ b/arch/x86/oprofile/nmi_int.c +@@ -23,6 +23,7 @@ + #include <asm/nmi.h> + #include <asm/msr.h> + #include <asm/apic.h> ++#include <asm/pgtable.h> + + #include "op_counter.h" + #include "op_x86_model.h" +@@ -774,8 +775,11 @@ int __init op_nmi_init(struct oprofile_operations *ops) + if (ret) + return ret; + +- if (!model->num_virt_counters) +- model->num_virt_counters = model->num_counters; ++ if (!model->num_virt_counters) { ++ pax_open_kernel(); ++ *(unsigned int *)&model->num_virt_counters = model->num_counters; ++ pax_close_kernel(); ++ } + + mux_init(ops); + +diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c +index b2b9443..be58856 100644 +--- a/arch/x86/oprofile/op_model_amd.c ++++ b/arch/x86/oprofile/op_model_amd.c +@@ -519,9 +519,11 @@ static int op_amd_init(struct oprofile_operations *ops) + num_counters = AMD64_NUM_COUNTERS; + } + +- op_amd_spec.num_counters = num_counters; +- op_amd_spec.num_controls = num_counters; +- op_amd_spec.num_virt_counters = max(num_counters, NUM_VIRT_COUNTERS); ++ pax_open_kernel(); ++ *(unsigned int *)&op_amd_spec.num_counters = num_counters; ++ *(unsigned int *)&op_amd_spec.num_controls = num_counters; ++ *(unsigned int *)&op_amd_spec.num_virt_counters = max(num_counters, NUM_VIRT_COUNTERS); ++ pax_close_kernel(); + + return 0; + } +diff --git a/arch/x86/oprofile/op_model_ppro.c b/arch/x86/oprofile/op_model_ppro.c +index d90528e..0127e2b 100644 +--- a/arch/x86/oprofile/op_model_ppro.c ++++ b/arch/x86/oprofile/op_model_ppro.c +@@ -19,6 +19,7 @@ + #include <asm/msr.h> + #include <asm/apic.h> + #include <asm/nmi.h> ++#include <asm/pgtable.h> + + #include "op_x86_model.h" + #include "op_counter.h" +@@ -221,8 +222,10 @@ static void arch_perfmon_setup_counters(void) + + num_counters = min((int)eax.split.num_counters, OP_MAX_COUNTER); + +- op_arch_perfmon_spec.num_counters = num_counters; +- op_arch_perfmon_spec.num_controls = num_counters; ++ pax_open_kernel(); ++ *(unsigned int *)&op_arch_perfmon_spec.num_counters = num_counters; ++ *(unsigned int *)&op_arch_perfmon_spec.num_controls = num_counters; ++ pax_close_kernel(); + } + + static int arch_perfmon_init(struct oprofile_operations *ignore) +diff --git a/arch/x86/oprofile/op_x86_model.h b/arch/x86/oprofile/op_x86_model.h +index 71e8a67..6a313bb 100644 +--- a/arch/x86/oprofile/op_x86_model.h ++++ b/arch/x86/oprofile/op_x86_model.h +@@ -52,7 +52,7 @@ struct op_x86_model_spec { + void (*switch_ctrl)(struct op_x86_model_spec const *model, + struct op_msrs const * const msrs); + #endif +-}; ++} __do_const; + + struct op_counter_config; + diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index e9e6ed5..e47ae67 100644 --- a/arch/x86/pci/amd_bus.c @@ -29030,6 +29399,46 @@ index e9e6ed5..e47ae67 100644 .notifier_call = amd_cpu_notify, }; +diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c +index 372e9b8..e775a6c 100644 +--- a/arch/x86/pci/irq.c ++++ b/arch/x86/pci/irq.c +@@ -50,7 +50,7 @@ struct irq_router { + struct irq_router_handler { + u16 vendor; + int (*probe)(struct irq_router *r, struct pci_dev *router, u16 device); +-}; ++} __do_const; + + int (*pcibios_enable_irq)(struct pci_dev *dev) = pirq_enable_irq; + void (*pcibios_disable_irq)(struct pci_dev *dev) = NULL; +@@ -794,7 +794,7 @@ static __init int pico_router_probe(struct irq_router *r, struct pci_dev *router + return 0; + } + +-static __initdata struct irq_router_handler pirq_routers[] = { ++static __initconst const struct irq_router_handler pirq_routers[] = { + { PCI_VENDOR_ID_INTEL, intel_router_probe }, + { PCI_VENDOR_ID_AL, ali_router_probe }, + { PCI_VENDOR_ID_ITE, ite_router_probe }, +@@ -821,7 +821,7 @@ static struct pci_dev *pirq_router_dev; + static void __init pirq_find_router(struct irq_router *r) + { + struct irq_routing_table *rt = pirq_table; +- struct irq_router_handler *h; ++ const struct irq_router_handler *h; + + #ifdef CONFIG_PCI_BIOS + if (!rt->signature) { +@@ -1094,7 +1094,7 @@ static int __init fix_acer_tm360_irqrouting(const struct dmi_system_id *d) + return 0; + } + +-static struct dmi_system_id __initdata pciirq_dmi_table[] = { ++static const struct dmi_system_id __initconst pciirq_dmi_table[] = { + { + .callback = fix_broken_hp_bios_irq9, + .ident = "HP Pavilion N5400 Series Laptop", diff --git a/arch/x86/pci/mrst.c b/arch/x86/pci/mrst.c index 6eb18c4..20d83de 100644 --- a/arch/x86/pci/mrst.c @@ -30909,6 +31318,19 @@ index f426330f..929058a 100644 rhash.blocksize = alg->cra_blocksize; rhash.digestsize = salg->digestsize; +diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h +index f220d64..d359ad6 100644 +--- a/drivers/acpi/apei/apei-internal.h ++++ b/drivers/acpi/apei/apei-internal.h +@@ -20,7 +20,7 @@ typedef int (*apei_exec_ins_func_t)(struct apei_exec_context *ctx, + struct apei_exec_ins_type { + u32 flags; + apei_exec_ins_func_t run; +-}; ++} __do_const; + + struct apei_exec_context { + u32 ip; diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c index e6defd8..c26a225 100644 --- a/drivers/acpi/apei/cper.c @@ -30930,6 +31352,36 @@ index e6defd8..c26a225 100644 } EXPORT_SYMBOL_GPL(cper_next_record_id); +diff --git a/drivers/acpi/bgrt.c b/drivers/acpi/bgrt.c +index be60399..778b33e8 100644 +--- a/drivers/acpi/bgrt.c ++++ b/drivers/acpi/bgrt.c +@@ -87,8 +87,10 @@ static int __init bgrt_init(void) + return -ENODEV; + + sysfs_bin_attr_init(&image_attr); +- image_attr.private = bgrt_image; +- image_attr.size = bgrt_image_size; ++ pax_open_kernel(); ++ *(void **)&image_attr.private = bgrt_image; ++ *(size_t *)&image_attr.size = bgrt_image_size; ++ pax_close_kernel(); + + bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj); + if (!bgrt_kobj) +diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c +index cb96296..2d6082b 100644 +--- a/drivers/acpi/blacklist.c ++++ b/drivers/acpi/blacklist.c +@@ -193,7 +193,7 @@ static int __init dmi_disable_osi_win7(const struct dmi_system_id *d) + return 0; + } + +-static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { ++static const struct dmi_system_id acpi_osi_dmi_table[] __initconst = { + { + .callback = dmi_disable_osi_vista, + .ident = "Fujitsu Siemens", diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c index 7586544..636a2f0 100644 --- a/drivers/acpi/ec_sys.c @@ -30996,6 +31448,37 @@ index e83311b..142b5cc 100644 /* * Buggy BIOS check +diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c +index ed9a1cc..f4a354c 100644 +--- a/drivers/acpi/processor_idle.c ++++ b/drivers/acpi/processor_idle.c +@@ -1005,7 +1005,7 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr) + { + int i, count = CPUIDLE_DRIVER_STATE_START; + struct acpi_processor_cx *cx; +- struct cpuidle_state *state; ++ cpuidle_state_no_const *state; + struct cpuidle_driver *drv = &acpi_idle_driver; + + if (!pr->flags.power_setup_done) +diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c +index ea61ca9..3fdd70d 100644 +--- a/drivers/acpi/sysfs.c ++++ b/drivers/acpi/sysfs.c +@@ -420,11 +420,11 @@ static u32 num_counters; + static struct attribute **all_attrs; + static u32 acpi_gpe_count; + +-static struct attribute_group interrupt_stats_attr_group = { ++static attribute_group_no_const interrupt_stats_attr_group = { + .name = "interrupts", + }; + +-static struct kobj_attribute *counter_attrs; ++static kobj_attribute_no_const *counter_attrs; + + static void delete_gpe_attr_array(void) + { diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 46cd3f4..0871ad0 100644 --- a/drivers/ata/libata-core.c @@ -32048,6 +32531,28 @@ index 969c3c2..9b72956 100644 wake_up(&zatm_vcc->tx_wait); } +diff --git a/drivers/base/bus.c b/drivers/base/bus.c +index 6856303..0602d70 100644 +--- a/drivers/base/bus.c ++++ b/drivers/base/bus.c +@@ -1163,7 +1163,7 @@ int subsys_interface_register(struct subsys_interface *sif) + return -EINVAL; + + mutex_lock(&subsys->p->mutex); +- list_add_tail(&sif->node, &subsys->p->interfaces); ++ pax_list_add_tail((struct list_head *)&sif->node, &subsys->p->interfaces); + if (sif->add_dev) { + subsys_dev_iter_init(&iter, subsys, NULL, NULL); + while ((dev = subsys_dev_iter_next(&iter))) +@@ -1188,7 +1188,7 @@ void subsys_interface_unregister(struct subsys_interface *sif) + subsys = sif->subsys; + + mutex_lock(&subsys->p->mutex); +- list_del_init(&sif->node); ++ pax_list_del_init((struct list_head *)&sif->node); + if (sif->remove_dev) { + subsys_dev_iter_init(&iter, subsys, NULL, NULL); + while ((dev = subsys_dev_iter_next(&iter))) diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 17cf7ca..7e553e1 100644 --- a/drivers/base/devtmpfs.c @@ -32061,6 +32566,41 @@ index 17cf7ca..7e553e1 100644 if (err) printk(KERN_INFO "devtmpfs: error mounting %i\n", err); else +diff --git a/drivers/base/node.c b/drivers/base/node.c +index fac124a..66bd4ab 100644 +--- a/drivers/base/node.c ++++ b/drivers/base/node.c +@@ -625,7 +625,7 @@ static ssize_t print_nodes_state(enum node_states state, char *buf) + struct node_attr { + struct device_attribute attr; + enum node_states state; +-}; ++} __do_const; + + static ssize_t show_node_state(struct device *dev, + struct device_attribute *attr, char *buf) +diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c +index acc3a8d..981c236 100644 +--- a/drivers/base/power/domain.c ++++ b/drivers/base/power/domain.c +@@ -1851,7 +1851,7 @@ int pm_genpd_attach_cpuidle(struct generic_pm_domain *genpd, int state) + { + struct cpuidle_driver *cpuidle_drv; + struct gpd_cpu_data *cpu_data; +- struct cpuidle_state *idle_state; ++ cpuidle_state_no_const *idle_state; + int ret = 0; + + if (IS_ERR_OR_NULL(genpd) || state < 0) +@@ -1919,7 +1919,7 @@ int pm_genpd_name_attach_cpuidle(const char *name, int state) + int pm_genpd_detach_cpuidle(struct generic_pm_domain *genpd) + { + struct gpd_cpu_data *cpu_data; +- struct cpuidle_state *idle_state; ++ cpuidle_state_no_const *idle_state; + int ret = 0; + + if (IS_ERR_OR_NULL(genpd)) diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index e6ee5e8..98ad7fc 100644 --- a/drivers/base/power/wakeup.c @@ -32100,6 +32640,28 @@ index e6ee5e8..98ad7fc 100644 trace_wakeup_source_deactivate(ws->name, cec); split_counters(&cnt, &inpr); +diff --git a/drivers/base/syscore.c b/drivers/base/syscore.c +index e8d11b6..7b1b36f 100644 +--- a/drivers/base/syscore.c ++++ b/drivers/base/syscore.c +@@ -21,7 +21,7 @@ static DEFINE_MUTEX(syscore_ops_lock); + void register_syscore_ops(struct syscore_ops *ops) + { + mutex_lock(&syscore_ops_lock); +- list_add_tail(&ops->node, &syscore_ops_list); ++ pax_list_add_tail((struct list_head *)&ops->node, &syscore_ops_list); + mutex_unlock(&syscore_ops_lock); + } + EXPORT_SYMBOL_GPL(register_syscore_ops); +@@ -33,7 +33,7 @@ EXPORT_SYMBOL_GPL(register_syscore_ops); + void unregister_syscore_ops(struct syscore_ops *ops) + { + mutex_lock(&syscore_ops_lock); +- list_del(&ops->node); ++ pax_list_del((struct list_head *)&ops->node); + mutex_unlock(&syscore_ops_lock); + } + EXPORT_SYMBOL_GPL(unregister_syscore_ops); diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index ade58bc..867143d 100644 --- a/drivers/block/cciss.c @@ -32438,7 +33000,7 @@ index 8c13eeb..217adee 100644 idr_destroy(&tconn->volumes); diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c -index a9eccfc..68e4533 100644 +index a9eccfc..f5efe87 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -833,7 +833,7 @@ int drbd_connected(struct drbd_conf *mdev) @@ -32509,6 +33071,15 @@ index a9eccfc..68e4533 100644 atomic_inc(&peer_req->epoch->active); spin_unlock(&tconn->epoch_lock); +@@ -4346,7 +4346,7 @@ struct data_cmd { + int expect_payload; + size_t pkt_size; + int (*fn)(struct drbd_tconn *, struct packet_info *); +-}; ++} __do_const; + + static struct data_cmd drbd_cmd_handler[] = { + [P_DATA] = { 1, sizeof(struct p_data), receive_Data }, @@ -4466,7 +4466,7 @@ static void conn_disconnect(struct drbd_tconn *tconn) if (!list_empty(&tconn->current_epoch->list)) conn_err(tconn, "ASSERTION FAILED: tconn->current_epoch->list not empty\n"); @@ -32518,6 +33089,15 @@ index a9eccfc..68e4533 100644 tconn->send.seen_any_write_yet = false; conn_info(tconn, "Connection closed\n"); +@@ -5222,7 +5222,7 @@ static int tconn_finish_peer_reqs(struct drbd_tconn *tconn) + struct asender_cmd { + size_t pkt_size; + int (*fn)(struct drbd_tconn *tconn, struct packet_info *); +-}; ++} __do_const; + + static struct asender_cmd asender_tbl[] = { + [P_PING] = { 0, got_Ping }, diff --git a/drivers/block/loop.c b/drivers/block/loop.c index ae12512..37fa397 100644 --- a/drivers/block/loop.c @@ -32930,7 +33510,7 @@ index b66eaa0..2619d1b 100644 if (cmd != SIOCWANDEV) diff --git a/drivers/char/random.c b/drivers/char/random.c -index 85e81ec..bce8b97 100644 +index 85e81ec..a129a39 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -272,8 +272,13 @@ @@ -32994,6 +33574,15 @@ index 85e81ec..bce8b97 100644 static int max_write_thresh = INPUT_POOL_WORDS * 32; static char sysctl_bootid[16]; +@@ -1372,7 +1384,7 @@ static char sysctl_bootid[16]; + static int proc_do_uuid(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { +- ctl_table fake_table; ++ ctl_table_no_const fake_table; + unsigned char buf[64], tmp_uuid[16], *uuid; + + uuid = table->data; diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index d780295..b29f3a8 100644 --- a/drivers/char/sonypi.c @@ -33134,8 +33723,86 @@ index 8ae1a61..9c00613 100644 .notifier_call = arch_timer_cpu_notify, }; +diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c +index fce2000..1110478 100644 +--- a/drivers/connector/cn_proc.c ++++ b/drivers/connector/cn_proc.c +@@ -313,6 +313,12 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, + (task_active_pid_ns(current) != &init_pid_ns)) + return; + ++ /* Can only change if privileged. */ ++ if (!capable(CAP_NET_ADMIN)) { ++ err = EPERM; ++ goto out; ++ } ++ + mc_op = (enum proc_cn_mcast_op *)msg->data; + switch (*mc_op) { + case PROC_CN_MCAST_LISTEN: +@@ -325,6 +331,8 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, + err = EINVAL; + break; + } ++ ++out: + cn_proc_ack(err, msg->seq, msg->ack); + } + +diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c +index 7b0d49d..134fac9 100644 +--- a/drivers/cpufreq/acpi-cpufreq.c ++++ b/drivers/cpufreq/acpi-cpufreq.c +@@ -172,7 +172,7 @@ static ssize_t show_global_boost(struct kobject *kobj, + return sprintf(buf, "%u\n", boost_enabled); + } + +-static struct global_attr global_boost = __ATTR(boost, 0644, ++static global_attr_no_const global_boost = __ATTR(boost, 0644, + show_global_boost, + store_global_boost); + +@@ -712,8 +712,11 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) + data->acpi_data = per_cpu_ptr(acpi_perf_data, cpu); + per_cpu(acfreq_data, cpu) = data; + +- if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) +- acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS; ++ if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) { ++ pax_open_kernel(); ++ *(u8 *)&acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS; ++ pax_close_kernel(); ++ } + + result = acpi_processor_register_performance(data->acpi_data, cpu); + if (result) +@@ -835,7 +838,9 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) + policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu); + break; + case ACPI_ADR_SPACE_FIXED_HARDWARE: +- acpi_cpufreq_driver.get = get_cur_freq_on_cpu; ++ pax_open_kernel(); ++ *(void **)&acpi_cpufreq_driver.get = get_cur_freq_on_cpu; ++ pax_close_kernel(); + policy->cur = get_cur_freq_on_cpu(cpu); + break; + default: +@@ -846,8 +851,11 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) + acpi_processor_notify_smm(THIS_MODULE); + + /* Check for APERF/MPERF support in hardware */ +- if (boot_cpu_has(X86_FEATURE_APERFMPERF)) +- acpi_cpufreq_driver.getavg = cpufreq_get_measured_perf; ++ if (boot_cpu_has(X86_FEATURE_APERFMPERF)) { ++ pax_open_kernel(); ++ *(void **)&acpi_cpufreq_driver.getavg = cpufreq_get_measured_perf; ++ pax_close_kernel(); ++ } + + pr_debug("CPU%u - ACPI performance management activated.\n", cpu); + for (i = 0; i < perf->state_count; i++) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c -index 1f93dbd..edf95ff 100644 +index 1f93dbd..305cef1 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1843,7 +1843,7 @@ static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb, @@ -33147,6 +33814,73 @@ index 1f93dbd..edf95ff 100644 .notifier_call = cpufreq_cpu_callback, }; +@@ -1875,8 +1875,11 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) + + pr_debug("trying to register driver %s\n", driver_data->name); + +- if (driver_data->setpolicy) +- driver_data->flags |= CPUFREQ_CONST_LOOPS; ++ if (driver_data->setpolicy) { ++ pax_open_kernel(); ++ *(u8 *)&driver_data->flags |= CPUFREQ_CONST_LOOPS; ++ pax_close_kernel(); ++ } + + spin_lock_irqsave(&cpufreq_driver_lock, flags); + if (cpufreq_driver) { +diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c +index 6c5f1d3..c7e2f35e 100644 +--- a/drivers/cpufreq/cpufreq_governor.c ++++ b/drivers/cpufreq/cpufreq_governor.c +@@ -243,7 +243,7 @@ int cpufreq_governor_dbs(struct dbs_data *dbs_data, + * governor, thus we are bound to jiffes/HZ + */ + if (dbs_data->governor == GOV_CONSERVATIVE) { +- struct cs_ops *ops = dbs_data->gov_ops; ++ const struct cs_ops *ops = dbs_data->gov_ops; + + cpufreq_register_notifier(ops->notifier_block, + CPUFREQ_TRANSITION_NOTIFIER); +@@ -251,7 +251,7 @@ int cpufreq_governor_dbs(struct dbs_data *dbs_data, + dbs_data->min_sampling_rate = MIN_SAMPLING_RATE_RATIO * + jiffies_to_usecs(10); + } else { +- struct od_ops *ops = dbs_data->gov_ops; ++ const struct od_ops *ops = dbs_data->gov_ops; + + od_tuners->io_is_busy = ops->io_busy(); + } +@@ -268,7 +268,7 @@ second_time: + cs_dbs_info->enable = 1; + cs_dbs_info->requested_freq = policy->cur; + } else { +- struct od_ops *ops = dbs_data->gov_ops; ++ const struct od_ops *ops = dbs_data->gov_ops; + od_dbs_info->rate_mult = 1; + od_dbs_info->sample_type = OD_NORMAL_SAMPLE; + ops->powersave_bias_init_cpu(cpu); +@@ -289,7 +289,7 @@ second_time: + mutex_destroy(&cpu_cdbs->timer_mutex); + dbs_data->enable--; + if (!dbs_data->enable) { +- struct cs_ops *ops = dbs_data->gov_ops; ++ const struct cs_ops *ops = dbs_data->gov_ops; + + sysfs_remove_group(cpufreq_global_kobject, + dbs_data->attr_group); +diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h +index f661654..6c8e638 100644 +--- a/drivers/cpufreq/cpufreq_governor.h ++++ b/drivers/cpufreq/cpufreq_governor.h +@@ -142,7 +142,7 @@ struct dbs_data { + void (*gov_check_cpu)(int cpu, unsigned int load); + + /* Governor specific ops, see below */ +- void *gov_ops; ++ const void *gov_ops; + }; + + /* Governor specific ops, will be passed to dbs_data->gov_ops */ diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 9d7732b..0b1a793 100644 --- a/drivers/cpufreq/cpufreq_stats.c @@ -33160,6 +33894,126 @@ index 9d7732b..0b1a793 100644 .notifier_call = cpufreq_stat_cpu_callback, .priority = 1, }; +diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c +index 827629c9..0bc6a03 100644 +--- a/drivers/cpufreq/p4-clockmod.c ++++ b/drivers/cpufreq/p4-clockmod.c +@@ -167,10 +167,14 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c) + case 0x0F: /* Core Duo */ + case 0x16: /* Celeron Core */ + case 0x1C: /* Atom */ +- p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; ++ pax_open_kernel(); ++ *(u8 *)&p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; ++ pax_close_kernel(); + return speedstep_get_frequency(SPEEDSTEP_CPU_PCORE); + case 0x0D: /* Pentium M (Dothan) */ +- p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; ++ pax_open_kernel(); ++ *(u8 *)&p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; ++ pax_close_kernel(); + /* fall through */ + case 0x09: /* Pentium M (Banias) */ + return speedstep_get_frequency(SPEEDSTEP_CPU_PM); +@@ -182,7 +186,9 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c) + + /* on P-4s, the TSC runs with constant frequency independent whether + * throttling is active or not. */ +- p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; ++ pax_open_kernel(); ++ *(u8 *)&p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS; ++ pax_close_kernel(); + + if (speedstep_detect_processor() == SPEEDSTEP_CPU_P4M) { + printk(KERN_WARNING PFX "Warning: Pentium 4-M detected. " +diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c +index 3a953d5..f5993f6 100644 +--- a/drivers/cpufreq/speedstep-centrino.c ++++ b/drivers/cpufreq/speedstep-centrino.c +@@ -353,8 +353,11 @@ static int centrino_cpu_init(struct cpufreq_policy *policy) + !cpu_has(cpu, X86_FEATURE_EST)) + return -ENODEV; + +- if (cpu_has(cpu, X86_FEATURE_CONSTANT_TSC)) +- centrino_driver.flags |= CPUFREQ_CONST_LOOPS; ++ if (cpu_has(cpu, X86_FEATURE_CONSTANT_TSC)) { ++ pax_open_kernel(); ++ *(u8 *)¢rino_driver.flags |= CPUFREQ_CONST_LOOPS; ++ pax_close_kernel(); ++ } + + if (policy->cpu != 0) + return -ENODEV; +diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c +index e1f6860..f8de20b 100644 +--- a/drivers/cpuidle/cpuidle.c ++++ b/drivers/cpuidle/cpuidle.c +@@ -279,7 +279,7 @@ static int poll_idle(struct cpuidle_device *dev, + + static void poll_idle_init(struct cpuidle_driver *drv) + { +- struct cpuidle_state *state = &drv->states[0]; ++ cpuidle_state_no_const *state = &drv->states[0]; + + snprintf(state->name, CPUIDLE_NAME_LEN, "POLL"); + snprintf(state->desc, CPUIDLE_DESC_LEN, "CPUIDLE CORE POLL IDLE"); +diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c +index ea2f8e7..70ac501 100644 +--- a/drivers/cpuidle/governor.c ++++ b/drivers/cpuidle/governor.c +@@ -87,7 +87,7 @@ int cpuidle_register_governor(struct cpuidle_governor *gov) + mutex_lock(&cpuidle_lock); + if (__cpuidle_find_governor(gov->name) == NULL) { + ret = 0; +- list_add_tail(&gov->governor_list, &cpuidle_governors); ++ pax_list_add_tail((struct list_head *)&gov->governor_list, &cpuidle_governors); + if (!cpuidle_curr_governor || + cpuidle_curr_governor->rating < gov->rating) + cpuidle_switch_governor(gov); +@@ -135,7 +135,7 @@ void cpuidle_unregister_governor(struct cpuidle_governor *gov) + new_gov = cpuidle_replace_governor(gov->rating); + cpuidle_switch_governor(new_gov); + } +- list_del(&gov->governor_list); ++ pax_list_del((struct list_head *)&gov->governor_list); + mutex_unlock(&cpuidle_lock); + } + +diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c +index 428754a..8bdf9cc 100644 +--- a/drivers/cpuidle/sysfs.c ++++ b/drivers/cpuidle/sysfs.c +@@ -131,7 +131,7 @@ static struct attribute *cpuidle_switch_attrs[] = { + NULL + }; + +-static struct attribute_group cpuidle_attr_group = { ++static attribute_group_no_const cpuidle_attr_group = { + .attrs = cpuidle_default_attrs, + .name = "cpuidle", + }; +diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c +index 3b36797..289c16a 100644 +--- a/drivers/devfreq/devfreq.c ++++ b/drivers/devfreq/devfreq.c +@@ -588,7 +588,7 @@ int devfreq_add_governor(struct devfreq_governor *governor) + goto err_out; + } + +- list_add(&governor->node, &devfreq_governor_list); ++ pax_list_add((struct list_head *)&governor->node, &devfreq_governor_list); + + list_for_each_entry(devfreq, &devfreq_list, node) { + int ret = 0; +@@ -676,7 +676,7 @@ int devfreq_remove_governor(struct devfreq_governor *governor) + } + } + +- list_del(&governor->node); ++ pax_list_del((struct list_head *)&governor->node); + err_out: + mutex_unlock(&devfreq_list_lock); + diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c index b70709b..1d8d02a 100644 --- a/drivers/dma/sh/shdma.c @@ -33173,8 +34027,21 @@ index b70709b..1d8d02a 100644 .notifier_call = sh_dmae_nmi_handler, /* Run before NMI debug handler and KGDB */ +diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c +index 0ca1ca7..6e6f454 100644 +--- a/drivers/edac/edac_mc_sysfs.c ++++ b/drivers/edac/edac_mc_sysfs.c +@@ -148,7 +148,7 @@ static const char *edac_caps[] = { + struct dev_ch_attribute { + struct device_attribute attr; + int channel; +-}; ++} __do_const; + + #define DEVICE_CHANNEL(_name, _mode, _show, _store, _var) \ + struct dev_ch_attribute dev_attr_legacy_##_name = \ diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c -index 0056c4d..725934f 100644 +index 0056c4d..23b54d9 100644 --- a/drivers/edac/edac_pci_sysfs.c +++ b/drivers/edac/edac_pci_sysfs.c @@ -26,8 +26,8 @@ static int edac_pci_log_pe = 1; /* log PCI parity errors */ @@ -33188,6 +34055,15 @@ index 0056c4d..725934f 100644 static struct kobject *edac_pci_top_main_kobj; static atomic_t edac_pci_sysfs_refcount = ATOMIC_INIT(0); +@@ -235,7 +235,7 @@ struct edac_pci_dev_attribute { + void *value; + ssize_t(*show) (void *, char *); + ssize_t(*store) (void *, const char *, size_t); +-}; ++} __do_const; + + /* Set of show/store abstract level functions for PCI Parity object */ + static ssize_t edac_pci_dev_show(struct kobject *kobj, struct attribute *attr, @@ -579,7 +579,7 @@ static void edac_pci_dev_parity_test(struct pci_dev *dev) edac_printk(KERN_CRIT, EDAC_PCI, "Signaled System Error on %s\n", @@ -33300,6 +34176,19 @@ index f8d2287..5aaf4db 100644 return -EINVAL; r = kmalloc(sizeof(*r), GFP_KERNEL); +diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c +index af3e8aa..eb2f227 100644 +--- a/drivers/firewire/core-device.c ++++ b/drivers/firewire/core-device.c +@@ -232,7 +232,7 @@ EXPORT_SYMBOL(fw_device_enable_phys_dma); + struct config_rom_attribute { + struct device_attribute attr; + u32 key; +-}; ++} __do_const; + + static ssize_t show_immediate(struct device *dev, + struct device_attribute *dattr, char *buf) diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index 28a94c7..58da63a 100644 --- a/drivers/firewire/core-transaction.c @@ -33324,6 +34213,19 @@ index 515a42c..5ecf3ba 100644 void fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver, struct device *device); +diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c +index 94a58a0..f5eba42 100644 +--- a/drivers/firmware/dmi-id.c ++++ b/drivers/firmware/dmi-id.c +@@ -16,7 +16,7 @@ + struct dmi_device_attribute{ + struct device_attribute dev_attr; + int field; +-}; ++} __do_const; + #define to_dmi_dev_attr(_dev_attr) \ + container_of(_dev_attr, struct dmi_device_attribute, dev_attr) + diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 982f1f5..d21e5da 100644 --- a/drivers/firmware/dmi_scan.c @@ -33350,7 +34252,7 @@ index 982f1f5..d21e5da 100644 iounmap(buf); return 0; diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c -index bcb201c..f9782e5 100644 +index bcb201c..4fd34dd 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -133,7 +133,7 @@ struct efivar_attribute { @@ -33362,6 +34264,43 @@ index bcb201c..f9782e5 100644 #define PSTORE_EFI_ATTRIBUTES \ (EFI_VARIABLE_NON_VOLATILE | \ +@@ -1734,7 +1734,7 @@ efivar_create_sysfs_entry(struct efivars *efivars, + static int + create_efivars_bin_attributes(struct efivars *efivars) + { +- struct bin_attribute *attr; ++ bin_attribute_no_const *attr; + int error; + + /* new_var */ +diff --git a/drivers/firmware/google/memconsole.c b/drivers/firmware/google/memconsole.c +index 2a90ba6..07f3733 100644 +--- a/drivers/firmware/google/memconsole.c ++++ b/drivers/firmware/google/memconsole.c +@@ -147,7 +147,9 @@ static int __init memconsole_init(void) + if (!found_memconsole()) + return -ENODEV; + +- memconsole_bin_attr.size = memconsole_length; ++ pax_open_kernel(); ++ *(size_t *)&memconsole_bin_attr.size = memconsole_length; ++ pax_close_kernel(); + + ret = sysfs_create_bin_file(firmware_kobj, &memconsole_bin_attr); + +diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c +index 6f2306d..af9476a 100644 +--- a/drivers/gpio/gpio-ich.c ++++ b/drivers/gpio/gpio-ich.c +@@ -69,7 +69,7 @@ struct ichx_desc { + /* Some chipsets have quirks, let these use their own request/get */ + int (*request)(struct gpio_chip *chip, unsigned offset); + int (*get)(struct gpio_chip *chip, unsigned offset); +-}; ++} __do_const; + + static struct { + spinlock_t lock; diff --git a/drivers/gpio/gpio-vr41xx.c b/drivers/gpio/gpio-vr41xx.c index 9902732..64b62dd 100644 --- a/drivers/gpio/gpio-vr41xx.c @@ -33389,7 +34328,7 @@ index 7b2d378..cc947ea 100644 dev = crtc->dev; diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c -index be174ca..0bcbb71 100644 +index be174ca..7f38143 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -307,7 +307,7 @@ module_exit(drm_core_exit); @@ -33401,6 +34340,15 @@ index be174ca..0bcbb71 100644 { int len; +@@ -377,7 +377,7 @@ long drm_ioctl(struct file *filp, + struct drm_file *file_priv = filp->private_data; + struct drm_device *dev; + struct drm_ioctl_desc *ioctl; +- drm_ioctl_t *func; ++ drm_ioctl_no_const_t func; + unsigned int nr = DRM_IOCTL_NR(cmd); + int retcode = -EINVAL; + char stack_kdata[128]; @@ -390,7 +390,7 @@ long drm_ioctl(struct file *filp, return -ENODEV; @@ -33589,7 +34537,7 @@ index d4b20ce..77a8d41 100644 #if defined(__i386__) pgprot = pgprot_val(vma->vm_page_prot); diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c -index 2f4c434..764794b 100644 +index 2f4c434..dd12cd2 100644 --- a/drivers/gpu/drm/drm_ioc32.c +++ b/drivers/gpu/drm/drm_ioc32.c @@ -457,7 +457,7 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd, @@ -33610,6 +34558,36 @@ index 2f4c434..764794b 100644 if (__put_user(count, &request->count) || __put_user(list, &request->list)) +@@ -1016,7 +1016,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, + return 0; + } + +-drm_ioctl_compat_t *drm_compat_ioctls[] = { ++drm_ioctl_compat_t drm_compat_ioctls[] = { + [DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version, + [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE32)] = compat_drm_getunique, + [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP32)] = compat_drm_getmap, +@@ -1062,7 +1062,6 @@ drm_ioctl_compat_t *drm_compat_ioctls[] = { + long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) + { + unsigned int nr = DRM_IOCTL_NR(cmd); +- drm_ioctl_compat_t *fn; + int ret; + + /* Assume that ioctls without an explicit compat routine will just +@@ -1072,10 +1071,8 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) + if (nr >= ARRAY_SIZE(drm_compat_ioctls)) + return drm_ioctl(filp, cmd, arg); + +- fn = drm_compat_ioctls[nr]; +- +- if (fn != NULL) +- ret = (*fn) (filp, cmd, arg); ++ if (drm_compat_ioctls[nr] != NULL) ++ ret = (*drm_compat_ioctls[nr]) (filp, cmd, arg); + else + ret = drm_ioctl(filp, cmd, arg); + diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index e77bd8b..1571b85 100644 --- a/drivers/gpu/drm/drm_ioctl.c @@ -33781,6 +34759,41 @@ index 26d08bb..fccb984 100644 for (i = 0; i < count; i++) { char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr; +diff --git a/drivers/gpu/drm/i915/i915_ioc32.c b/drivers/gpu/drm/i915/i915_ioc32.c +index 3c59584..500f2e9 100644 +--- a/drivers/gpu/drm/i915/i915_ioc32.c ++++ b/drivers/gpu/drm/i915/i915_ioc32.c +@@ -181,7 +181,7 @@ static int compat_i915_alloc(struct file *file, unsigned int cmd, + (unsigned long)request); + } + +-static drm_ioctl_compat_t *i915_compat_ioctls[] = { ++static drm_ioctl_compat_t i915_compat_ioctls[] = { + [DRM_I915_BATCHBUFFER] = compat_i915_batchbuffer, + [DRM_I915_CMDBUFFER] = compat_i915_cmdbuffer, + [DRM_I915_GETPARAM] = compat_i915_getparam, +@@ -202,18 +202,15 @@ static drm_ioctl_compat_t *i915_compat_ioctls[] = { + long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) + { + unsigned int nr = DRM_IOCTL_NR(cmd); +- drm_ioctl_compat_t *fn = NULL; + int ret; + + if (nr < DRM_COMMAND_BASE) + return drm_compat_ioctl(filp, cmd, arg); + +- if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls)) +- fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE]; +- +- if (fn != NULL) ++ if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls)) { ++ drm_ioctl_compat_t fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE]; + ret = (*fn) (filp, cmd, arg); +- else ++ } else + ret = drm_ioctl(filp, cmd, arg); + + return ret; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index fe84338..a863190 100644 --- a/drivers/gpu/drm/i915/i915_irq.c @@ -33885,7 +34898,7 @@ index fe84338..a863190 100644 iir = I915_READ(IIR); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c -index 80aa1fc..1ede041 100644 +index 80aa1fc..85cfce3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2255,7 +2255,7 @@ intel_finish_fb(struct drm_framebuffer *old_fb) @@ -33925,6 +34938,53 @@ index 80aa1fc..1ede041 100644 drm_gem_object_unreference(&work->old_fb_obj->base); drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); +@@ -8849,13 +8848,13 @@ struct intel_quirk { + int subsystem_vendor; + int subsystem_device; + void (*hook)(struct drm_device *dev); +-}; ++} __do_const; + + /* For systems that don't have a meaningful PCI subdevice/subvendor ID */ + struct intel_dmi_quirk { + void (*hook)(struct drm_device *dev); + const struct dmi_system_id (*dmi_id_list)[]; +-}; ++} __do_const; + + static int intel_dmi_reverse_brightness(const struct dmi_system_id *id) + { +@@ -8863,18 +8862,20 @@ static int intel_dmi_reverse_brightness(const struct dmi_system_id *id) + return 1; + } + ++static const struct dmi_system_id intel_dmi_quirks_table[] = { ++ { ++ .callback = intel_dmi_reverse_brightness, ++ .ident = "NCR Corporation", ++ .matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"), ++ DMI_MATCH(DMI_PRODUCT_NAME, ""), ++ }, ++ }, ++ { } /* terminating entry */ ++}; ++ + static const struct intel_dmi_quirk intel_dmi_quirks[] = { + { +- .dmi_id_list = &(const struct dmi_system_id[]) { +- { +- .callback = intel_dmi_reverse_brightness, +- .ident = "NCR Corporation", +- .matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"), +- DMI_MATCH(DMI_PRODUCT_NAME, ""), +- }, +- }, +- { } /* terminating entry */ +- }, ++ .dmi_id_list = &intel_dmi_quirks_table, + .hook = quirk_invert_brightness, + }, + }; diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h index 54558a0..2d97005 100644 --- a/drivers/gpu/drm/mga/mga_drv.h @@ -33941,6 +35001,41 @@ index 54558a0..2d97005 100644 u32 next_fence_to_post; unsigned int fb_cpp; +diff --git a/drivers/gpu/drm/mga/mga_ioc32.c b/drivers/gpu/drm/mga/mga_ioc32.c +index 709e90d..89a1c0d 100644 +--- a/drivers/gpu/drm/mga/mga_ioc32.c ++++ b/drivers/gpu/drm/mga/mga_ioc32.c +@@ -189,7 +189,7 @@ static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd, + return 0; + } + +-drm_ioctl_compat_t *mga_compat_ioctls[] = { ++drm_ioctl_compat_t mga_compat_ioctls[] = { + [DRM_MGA_INIT] = compat_mga_init, + [DRM_MGA_GETPARAM] = compat_mga_getparam, + [DRM_MGA_DMA_BOOTSTRAP] = compat_mga_dma_bootstrap, +@@ -207,18 +207,15 @@ drm_ioctl_compat_t *mga_compat_ioctls[] = { + long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) + { + unsigned int nr = DRM_IOCTL_NR(cmd); +- drm_ioctl_compat_t *fn = NULL; + int ret; + + if (nr < DRM_COMMAND_BASE) + return drm_compat_ioctl(filp, cmd, arg); + +- if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls)) +- fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE]; +- +- if (fn != NULL) ++ if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls)) { ++ drm_ioctl_compat_t fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE]; + ret = (*fn) (filp, cmd, arg); +- else ++ } else + ret = drm_ioctl(filp, cmd, arg); + + return ret; diff --git a/drivers/gpu/drm/mga/mga_irq.c b/drivers/gpu/drm/mga/mga_irq.c index 598c281..60d590e 100644 --- a/drivers/gpu/drm/mga/mga_irq.c @@ -34033,6 +35128,19 @@ index 8bf695c..9fbc90a 100644 retry: if (++trycnt > 100000) { NV_ERROR(drm, "%s failed and gave up.\n", __func__); +diff --git a/drivers/gpu/drm/nouveau/nouveau_ioc32.c b/drivers/gpu/drm/nouveau/nouveau_ioc32.c +index 08214bc..9208577 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_ioc32.c ++++ b/drivers/gpu/drm/nouveau/nouveau_ioc32.c +@@ -50,7 +50,7 @@ long nouveau_compat_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) + { + unsigned int nr = DRM_IOCTL_NR(cmd); +- drm_ioctl_compat_t *fn = NULL; ++ drm_ioctl_compat_t fn = NULL; + int ret; + + if (nr < DRM_COMMAND_BASE) diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c index 25d3495..d81aaf6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vga.c @@ -34080,6 +35188,41 @@ index 930c71b..499aded 100644 u32 color_fmt; unsigned int front_offset; +diff --git a/drivers/gpu/drm/r128/r128_ioc32.c b/drivers/gpu/drm/r128/r128_ioc32.c +index a954c54..9cc595c 100644 +--- a/drivers/gpu/drm/r128/r128_ioc32.c ++++ b/drivers/gpu/drm/r128/r128_ioc32.c +@@ -177,7 +177,7 @@ static int compat_r128_getparam(struct file *file, unsigned int cmd, + return drm_ioctl(file, DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam); + } + +-drm_ioctl_compat_t *r128_compat_ioctls[] = { ++drm_ioctl_compat_t r128_compat_ioctls[] = { + [DRM_R128_INIT] = compat_r128_init, + [DRM_R128_DEPTH] = compat_r128_depth, + [DRM_R128_STIPPLE] = compat_r128_stipple, +@@ -196,18 +196,15 @@ drm_ioctl_compat_t *r128_compat_ioctls[] = { + long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) + { + unsigned int nr = DRM_IOCTL_NR(cmd); +- drm_ioctl_compat_t *fn = NULL; + int ret; + + if (nr < DRM_COMMAND_BASE) + return drm_compat_ioctl(filp, cmd, arg); + +- if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(r128_compat_ioctls)) +- fn = r128_compat_ioctls[nr - DRM_COMMAND_BASE]; +- +- if (fn != NULL) ++ if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(r128_compat_ioctls)) { ++ drm_ioctl_compat_t fn = r128_compat_ioctls[nr - DRM_COMMAND_BASE]; + ret = (*fn) (filp, cmd, arg); +- else ++ } else + ret = drm_ioctl(filp, cmd, arg); + + return ret; diff --git a/drivers/gpu/drm/r128/r128_irq.c b/drivers/gpu/drm/r128/r128_irq.c index 2ea4f09..d391371 100644 --- a/drivers/gpu/drm/r128/r128_irq.c @@ -34167,7 +35310,7 @@ index e7fdf16..f4f6490 100644 uint32_t irq_enable_reg; uint32_t r500_disp_irq_reg; diff --git a/drivers/gpu/drm/radeon/radeon_ioc32.c b/drivers/gpu/drm/radeon/radeon_ioc32.c -index c180df8..cd80dd2d 100644 +index c180df8..5fd8186 100644 --- a/drivers/gpu/drm/radeon/radeon_ioc32.c +++ b/drivers/gpu/drm/radeon/radeon_ioc32.c @@ -358,7 +358,7 @@ static int compat_radeon_cp_setparam(struct file *file, unsigned int cmd, @@ -34179,6 +35322,37 @@ index c180df8..cd80dd2d 100644 &request->value)) return -EFAULT; +@@ -368,7 +368,7 @@ static int compat_radeon_cp_setparam(struct file *file, unsigned int cmd, + #define compat_radeon_cp_setparam NULL + #endif /* X86_64 || IA64 */ + +-static drm_ioctl_compat_t *radeon_compat_ioctls[] = { ++static drm_ioctl_compat_t radeon_compat_ioctls[] = { + [DRM_RADEON_CP_INIT] = compat_radeon_cp_init, + [DRM_RADEON_CLEAR] = compat_radeon_cp_clear, + [DRM_RADEON_STIPPLE] = compat_radeon_cp_stipple, +@@ -393,18 +393,15 @@ static drm_ioctl_compat_t *radeon_compat_ioctls[] = { + long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) + { + unsigned int nr = DRM_IOCTL_NR(cmd); +- drm_ioctl_compat_t *fn = NULL; + int ret; + + if (nr < DRM_COMMAND_BASE) + return drm_compat_ioctl(filp, cmd, arg); + +- if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_ioctls)) +- fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE]; +- +- if (fn != NULL) ++ if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_ioctls)) { ++ drm_ioctl_compat_t fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE]; + ret = (*fn) (filp, cmd, arg); +- else ++ } else + ret = drm_ioctl(filp, cmd, arg); + + return ret; diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c index e771033..a0bc6b3 100644 --- a/drivers/gpu/drm/radeon/radeon_irq.c @@ -34226,7 +35400,7 @@ index 8e9057b..af6dacb 100644 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c -index 93f760e..33d9839 100644 +index 93f760e..8088227 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -782,7 +782,7 @@ void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size) @@ -34249,6 +35423,54 @@ index 93f760e..33d9839 100644 } vma->vm_ops = &radeon_ttm_vm_ops; return 0; +@@ -862,28 +864,33 @@ static int radeon_ttm_debugfs_init(struct radeon_device *rdev) + sprintf(radeon_mem_types_names[i], "radeon_vram_mm"); + else + sprintf(radeon_mem_types_names[i], "radeon_gtt_mm"); +- radeon_mem_types_list[i].name = radeon_mem_types_names[i]; +- radeon_mem_types_list[i].show = &radeon_mm_dump_table; +- radeon_mem_types_list[i].driver_features = 0; ++ pax_open_kernel(); ++ *(const char **)&radeon_mem_types_list[i].name = radeon_mem_types_names[i]; ++ *(void **)&radeon_mem_types_list[i].show = &radeon_mm_dump_table; ++ *(u32 *)&radeon_mem_types_list[i].driver_features = 0; + if (i == 0) +- radeon_mem_types_list[i].data = rdev->mman.bdev.man[TTM_PL_VRAM].priv; ++ *(void **)&radeon_mem_types_list[i].data = rdev->mman.bdev.man[TTM_PL_VRAM].priv; + else +- radeon_mem_types_list[i].data = rdev->mman.bdev.man[TTM_PL_TT].priv; +- ++ *(void **)&radeon_mem_types_list[i].data = rdev->mman.bdev.man[TTM_PL_TT].priv; ++ pax_close_kernel(); + } + /* Add ttm page pool to debugfs */ + sprintf(radeon_mem_types_names[i], "ttm_page_pool"); +- radeon_mem_types_list[i].name = radeon_mem_types_names[i]; +- radeon_mem_types_list[i].show = &ttm_page_alloc_debugfs; +- radeon_mem_types_list[i].driver_features = 0; +- radeon_mem_types_list[i++].data = NULL; ++ pax_open_kernel(); ++ *(const char **)&radeon_mem_types_list[i].name = radeon_mem_types_names[i]; ++ *(void **)&radeon_mem_types_list[i].show = &ttm_page_alloc_debugfs; ++ *(u32 *)&radeon_mem_types_list[i].driver_features = 0; ++ *(void **)&radeon_mem_types_list[i++].data = NULL; ++ pax_close_kernel(); + #ifdef CONFIG_SWIOTLB + if (swiotlb_nr_tbl()) { + sprintf(radeon_mem_types_names[i], "ttm_dma_page_pool"); +- radeon_mem_types_list[i].name = radeon_mem_types_names[i]; +- radeon_mem_types_list[i].show = &ttm_dma_page_alloc_debugfs; +- radeon_mem_types_list[i].driver_features = 0; +- radeon_mem_types_list[i++].data = NULL; ++ pax_open_kernel(); ++ *(const char **)&radeon_mem_types_list[i].name = radeon_mem_types_names[i]; ++ *(void **)&radeon_mem_types_list[i].show = &ttm_dma_page_alloc_debugfs; ++ *(u32 *)&radeon_mem_types_list[i].driver_features = 0; ++ *(void **)&radeon_mem_types_list[i++].data = NULL; ++ pax_close_kernel(); + } + #endif + return radeon_debugfs_add_files(rdev, radeon_mem_types_list, i); diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 5706d2a..17aedaa 100644 --- a/drivers/gpu/drm/radeon/rs690.c @@ -34282,6 +35504,18 @@ index bd2a3b4..122d9ad 100644 struct ttm_page_pool *pool; int shrink_pages = sc->nr_to_scan; +diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c +index 1eb060c..188b1fc 100644 +--- a/drivers/gpu/drm/udl/udl_fb.c ++++ b/drivers/gpu/drm/udl/udl_fb.c +@@ -367,7 +367,6 @@ static int udl_fb_release(struct fb_info *info, int user) + fb_deferred_io_cleanup(info); + kfree(info->fbdefio); + info->fbdefio = NULL; +- info->fbops->fb_mmap = udl_fb_mmap; + } + + pr_warn("released /dev/fb%d user=%d count=%d\n", diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h index 893a650..6190d3b 100644 --- a/drivers/gpu/drm/via/via_drv.h @@ -34559,6 +35793,69 @@ index 8e1a9ec..4687821 100644 child_device_obj->device.bus = &hv_bus; child_device_obj->device.parent = &hv_acpi_dev->dev; +diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c +index 1672e2a..4a6297c 100644 +--- a/drivers/hwmon/acpi_power_meter.c ++++ b/drivers/hwmon/acpi_power_meter.c +@@ -117,7 +117,7 @@ struct sensor_template { + struct device_attribute *devattr, + const char *buf, size_t count); + int index; +-}; ++} __do_const; + + /* Averaging interval */ + static int update_avg_interval(struct acpi_power_meter_resource *resource) +@@ -629,7 +629,7 @@ static int register_attrs(struct acpi_power_meter_resource *resource, + struct sensor_template *attrs) + { + struct device *dev = &resource->acpi_dev->dev; +- struct sensor_device_attribute *sensors = ++ sensor_device_attribute_no_const *sensors = + &resource->sensors[resource->num_sensors]; + int res = 0; + +diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c +index b41baff..4953e4d 100644 +--- a/drivers/hwmon/applesmc.c ++++ b/drivers/hwmon/applesmc.c +@@ -1084,7 +1084,7 @@ static int applesmc_create_nodes(struct applesmc_node_group *groups, int num) + { + struct applesmc_node_group *grp; + struct applesmc_dev_attr *node; +- struct attribute *attr; ++ attribute_no_const *attr; + int ret, i; + + for (grp = groups; grp->format; grp++) { +diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c +index 56dbcfb..9874bf1 100644 +--- a/drivers/hwmon/asus_atk0110.c ++++ b/drivers/hwmon/asus_atk0110.c +@@ -152,10 +152,10 @@ MODULE_DEVICE_TABLE(acpi, atk_ids); + struct atk_sensor_data { + struct list_head list; + struct atk_data *data; +- struct device_attribute label_attr; +- struct device_attribute input_attr; +- struct device_attribute limit1_attr; +- struct device_attribute limit2_attr; ++ device_attribute_no_const label_attr; ++ device_attribute_no_const input_attr; ++ device_attribute_no_const limit1_attr; ++ device_attribute_no_const limit2_attr; + char label_attr_name[ATTR_NAME_SIZE]; + char input_attr_name[ATTR_NAME_SIZE]; + char limit1_attr_name[ATTR_NAME_SIZE]; +@@ -275,7 +275,7 @@ static ssize_t atk_name_show(struct device *dev, + static struct device_attribute atk_name_attr = + __ATTR(name, 0444, atk_name_show, NULL); + +-static void atk_init_attribute(struct device_attribute *attr, char *name, ++static void atk_init_attribute(device_attribute_no_const *attr, char *name, + sysfs_show_func show) + { + sysfs_attr_init(&attr->attr); diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index d64923d..72591e8 100644 --- a/drivers/hwmon/coretemp.c @@ -34572,6 +35869,32 @@ index d64923d..72591e8 100644 .notifier_call = coretemp_cpu_callback, }; +diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c +index a14f634..2916ee2 100644 +--- a/drivers/hwmon/ibmaem.c ++++ b/drivers/hwmon/ibmaem.c +@@ -925,7 +925,7 @@ static int aem_register_sensors(struct aem_data *data, + struct aem_rw_sensor_template *rw) + { + struct device *dev = &data->pdev->dev; +- struct sensor_device_attribute *sensors = data->sensors; ++ sensor_device_attribute_no_const *sensors = data->sensors; + int err; + + /* Set up read-only sensors */ +diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c +index 7d19b1b..8fdaaac 100644 +--- a/drivers/hwmon/pmbus/pmbus_core.c ++++ b/drivers/hwmon/pmbus/pmbus_core.c +@@ -811,7 +811,7 @@ static ssize_t pmbus_show_label(struct device *dev, + + #define PMBUS_ADD_ATTR(data, _name, _idx, _mode, _type, _show, _set) \ + do { \ +- struct sensor_device_attribute *a \ ++ sensor_device_attribute_no_const *a \ + = &data->_type##s[data->num_##_type##s].attribute; \ + BUG_ON(data->num_attributes >= data->max_attributes); \ + sysfs_attr_init(&a->dev_attr.attr); \ diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 1c85d39..55ed3cf 100644 --- a/drivers/hwmon/sht15.c @@ -34676,6 +35999,19 @@ index 8126824..55a2798 100644 drive->dma = 0; } } +diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c +index 8848f16..f8e6dd8 100644 +--- a/drivers/iio/industrialio-core.c ++++ b/drivers/iio/industrialio-core.c +@@ -506,7 +506,7 @@ static ssize_t iio_write_channel_info(struct device *dev, + } + + static +-int __iio_device_attr_init(struct device_attribute *dev_attr, ++int __iio_device_attr_init(device_attribute_no_const *dev_attr, + const char *postfix, + struct iio_chan_spec const *chan, + ssize_t (*readfunc)(struct device *dev, diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 394fea2..c833880 100644 --- a/drivers/infiniband/core/cm.c @@ -35468,6 +36804,19 @@ index d6cbfe9..6225402 100644 snprintf(led->name, sizeof(led->name), "xpad%ld", led_no); led->xpad = xpad; +diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h +index fe1df23..5b710f3 100644 +--- a/drivers/input/mouse/psmouse.h ++++ b/drivers/input/mouse/psmouse.h +@@ -115,7 +115,7 @@ struct psmouse_attribute { + ssize_t (*set)(struct psmouse *psmouse, void *data, + const char *buf, size_t count); + bool protect; +-}; ++} __do_const; + #define to_psmouse_attr(a) container_of((a), struct psmouse_attribute, dattr) + + ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *attr, diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 4c842c3..590b0bf 100644 --- a/drivers/input/mousedev.c @@ -35503,6 +36852,19 @@ index 25fc597..558bf3b 100644 serio->dev.bus = &serio_bus; serio->dev.release = serio_release_port; serio->dev.groups = serio_device_attr_groups; +diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c +index ddbdaca..be18a78 100644 +--- a/drivers/iommu/iommu.c ++++ b/drivers/iommu/iommu.c +@@ -554,7 +554,7 @@ static struct notifier_block iommu_bus_nb = { + static void iommu_bus_init(struct bus_type *bus, struct iommu_ops *ops) + { + bus_register_notifier(bus, &iommu_bus_nb); +- bus_for_each_dev(bus, NULL, ops, add_iommu_group); ++ bus_for_each_dev(bus, NULL, (void *)ops, add_iommu_group); + } + + /** diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 89562a8..218999b 100644 --- a/drivers/isdn/capi/capi.c @@ -35672,6 +37034,32 @@ index e74df7c..03a03ba 100644 return -EFAULT; } else memcpy(msg, buf, count); +diff --git a/drivers/leds/leds-clevo-mail.c b/drivers/leds/leds-clevo-mail.c +index 6a8405d..0bd1c7e 100644 +--- a/drivers/leds/leds-clevo-mail.c ++++ b/drivers/leds/leds-clevo-mail.c +@@ -40,7 +40,7 @@ static int __init clevo_mail_led_dmi_callback(const struct dmi_system_id *id) + * detected as working, but in reality it is not) as low as + * possible. + */ +-static struct dmi_system_id __initdata clevo_mail_led_dmi_table[] = { ++static const struct dmi_system_id __initconst clevo_mail_led_dmi_table[] = { + { + .callback = clevo_mail_led_dmi_callback, + .ident = "Clevo D410J", +diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c +index ec9b287..65c9bf4 100644 +--- a/drivers/leds/leds-ss4200.c ++++ b/drivers/leds/leds-ss4200.c +@@ -92,7 +92,7 @@ MODULE_PARM_DESC(nodetect, "Skip DMI-based hardware detection"); + * detected as working, but in reality it is not) as low as + * possible. + */ +-static struct dmi_system_id __initdata nas_led_whitelist[] = { ++static const struct dmi_system_id __initconst nas_led_whitelist[] = { + { + .callback = ss4200_led_dmi_callback, + .ident = "Intel SS4200-E", diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c index a5ebc00..982886f 100644 --- a/drivers/lguest/core.c @@ -36583,6 +37971,29 @@ index 9382895..ac8093c 100644 /* debug */ static int dvb_usb_dw2102_debug; +diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c +index aa6e7c7..4cd8061 100644 +--- a/drivers/media/v4l2-core/v4l2-ioctl.c ++++ b/drivers/media/v4l2-core/v4l2-ioctl.c +@@ -1923,7 +1923,8 @@ struct v4l2_ioctl_info { + struct file *file, void *fh, void *p); + } u; + void (*debug)(const void *arg, bool write_only); +-}; ++} __do_const; ++typedef struct v4l2_ioctl_info __no_const v4l2_ioctl_info_no_const; + + /* This control needs a priority check */ + #define INFO_FL_PRIO (1 << 0) +@@ -2108,7 +2109,7 @@ static long __video_do_ioctl(struct file *file, + struct video_device *vfd = video_devdata(file); + const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; + bool write_only = false; +- struct v4l2_ioctl_info default_info; ++ v4l2_ioctl_info_no_const default_info; + const struct v4l2_ioctl_info *info; + void *fh = file->private_data; + struct v4l2_fh *vfh = NULL; diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c index 29b2172..a7c5b31 100644 --- a/drivers/memstick/host/r592.c @@ -36874,6 +38285,70 @@ index 45ece11..8efa218 100644 #include <linux/init.h> #include <linux/pci.h> #include <linux/interrupt.h> +diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c +index a5f9888..1c0ed56 100644 +--- a/drivers/mfd/twl4030-irq.c ++++ b/drivers/mfd/twl4030-irq.c +@@ -35,6 +35,7 @@ + #include <linux/of.h> + #include <linux/irqdomain.h> + #include <linux/i2c/twl.h> ++#include <asm/pgtable.h> + + #include "twl-core.h" + +@@ -728,10 +729,12 @@ int twl4030_init_irq(struct device *dev, int irq_num) + * Install an irq handler for each of the SIH modules; + * clone dummy irq_chip since PIH can't *do* anything + */ +- twl4030_irq_chip = dummy_irq_chip; +- twl4030_irq_chip.name = "twl4030"; ++ pax_open_kernel(); ++ memcpy((void *)&twl4030_irq_chip, &dummy_irq_chip, sizeof twl4030_irq_chip); ++ *(const char **)&twl4030_irq_chip.name = "twl4030"; + +- twl4030_sih_irq_chip.irq_ack = dummy_irq_chip.irq_ack; ++ *(void **)&twl4030_sih_irq_chip.irq_ack = dummy_irq_chip.irq_ack; ++ pax_close_kernel(); + + for (i = irq_base; i < irq_end; i++) { + irq_set_chip_and_handler(i, &twl4030_irq_chip, +diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c +index 277a8db..0e0b754 100644 +--- a/drivers/mfd/twl6030-irq.c ++++ b/drivers/mfd/twl6030-irq.c +@@ -387,10 +387,12 @@ int twl6030_init_irq(struct device *dev, int irq_num) + * install an irq handler for each of the modules; + * clone dummy irq_chip since PIH can't *do* anything + */ +- twl6030_irq_chip = dummy_irq_chip; +- twl6030_irq_chip.name = "twl6030"; +- twl6030_irq_chip.irq_set_type = NULL; +- twl6030_irq_chip.irq_set_wake = twl6030_irq_set_wake; ++ pax_open_kernel(); ++ memcpy((void *)&twl6030_irq_chip, &dummy_irq_chip, sizeof twl6030_irq_chip); ++ *(const char **)&twl6030_irq_chip.name = "twl6030"; ++ *(void **)&twl6030_irq_chip.irq_set_type = NULL; ++ *(void **)&twl6030_irq_chip.irq_set_wake = twl6030_irq_set_wake; ++ pax_close_kernel(); + + for (i = irq_base; i < irq_end; i++) { + irq_set_chip_and_handler(i, &twl6030_irq_chip, +diff --git a/drivers/misc/c2port/core.c b/drivers/misc/c2port/core.c +index f428d86..274c368 100644 +--- a/drivers/misc/c2port/core.c ++++ b/drivers/misc/c2port/core.c +@@ -924,7 +924,9 @@ struct c2port_device *c2port_device_register(char *name, + mutex_init(&c2dev->mutex); + + /* Create binary file */ +- c2port_bin_attrs.size = ops->blocks_num * ops->block_size; ++ pax_open_kernel(); ++ *(size_t *)&c2port_bin_attrs.size = ops->blocks_num * ops->block_size; ++ pax_close_kernel(); + ret = device_create_bin_file(c2dev->dev, &c2port_bin_attrs); + if (unlikely(ret)) + goto error_device_create_bin_file; diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c index 3aa9a96..59cf685 100644 --- a/drivers/misc/kgdbts.c @@ -37308,6 +38783,32 @@ index 51b9d6a..52af9a7 100644 #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> #include <linux/mtd/nftl.h> +diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c +index 8dd6ba5..419cc1d 100644 +--- a/drivers/mtd/sm_ftl.c ++++ b/drivers/mtd/sm_ftl.c +@@ -56,7 +56,7 @@ ssize_t sm_attr_show(struct device *dev, struct device_attribute *attr, + #define SM_CIS_VENDOR_OFFSET 0x59 + struct attribute_group *sm_create_sysfs_attributes(struct sm_ftl *ftl) + { +- struct attribute_group *attr_group; ++ attribute_group_no_const *attr_group; + struct attribute **attributes; + struct sm_sysfs_attribute *vendor_attribute; + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index b7d45f3..b5c89d9 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -4861,7 +4861,7 @@ static unsigned int bond_get_num_tx_queues(void) + return tx_queues; + } + +-static struct rtnl_link_ops bond_link_ops __read_mostly = { ++static struct rtnl_link_ops bond_link_ops = { + .kind = "bond", + .priv_size = sizeof(struct bonding), + .setup = bond_setup, diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c index 70dba5d..11a0919 100644 --- a/drivers/net/ethernet/8390/ax88796.c @@ -37609,10 +39110,33 @@ index 1e9cb0b..7839125 100644 priv = netdev_priv(dev); priv->phy = phy; diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c -index d3fb97d..e229d3e 100644 +index d3fb97d..19520c7 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c -@@ -913,7 +913,7 @@ static int macvlan_device_event(struct notifier_block *unused, +@@ -851,13 +851,15 @@ static const struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX + 1] = { + int macvlan_link_register(struct rtnl_link_ops *ops) + { + /* common fields */ +- ops->priv_size = sizeof(struct macvlan_dev); +- ops->validate = macvlan_validate; +- ops->maxtype = IFLA_MACVLAN_MAX; +- ops->policy = macvlan_policy; +- ops->changelink = macvlan_changelink; +- ops->get_size = macvlan_get_size; +- ops->fill_info = macvlan_fill_info; ++ pax_open_kernel(); ++ *(size_t *)&ops->priv_size = sizeof(struct macvlan_dev); ++ *(void **)&ops->validate = macvlan_validate; ++ *(int *)&ops->maxtype = IFLA_MACVLAN_MAX; ++ *(const void **)&ops->policy = macvlan_policy; ++ *(void **)&ops->changelink = macvlan_changelink; ++ *(void **)&ops->get_size = macvlan_get_size; ++ *(void **)&ops->fill_info = macvlan_fill_info; ++ pax_close_kernel(); + + return rtnl_link_register(ops); + }; +@@ -913,7 +915,7 @@ static int macvlan_device_event(struct notifier_block *unused, return NOTIFY_DONE; } @@ -37795,6 +39319,19 @@ index cd8ccb2..cff5144 100644 result = hso_start_serial_device(serial_table[i], GFP_NOIO); hso_kick_transmit(dev2ser(serial_table[i])); +diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c +index 656230e..15525a8 100644 +--- a/drivers/net/vxlan.c ++++ b/drivers/net/vxlan.c +@@ -1428,7 +1428,7 @@ nla_put_failure: + return -EMSGSIZE; + } + +-static struct rtnl_link_ops vxlan_link_ops __read_mostly = { ++static struct rtnl_link_ops vxlan_link_ops = { + .kind = "vxlan", + .maxtype = IFLA_VXLAN_MAX, + .policy = vxlan_policy, diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 8d78253..bebbb68 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c @@ -38489,6 +40026,21 @@ index 3f56bc0..707d642 100644 } #endif /* IEEE1284.3 support. */ +diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c +index c35e8ad..fc33beb 100644 +--- a/drivers/pci/hotplug/acpiphp_ibm.c ++++ b/drivers/pci/hotplug/acpiphp_ibm.c +@@ -464,7 +464,9 @@ static int __init ibm_acpiphp_init(void) + goto init_cleanup; + } + +- ibm_apci_table_attr.size = ibm_get_table_from_acpi(NULL); ++ pax_open_kernel(); ++ *(size_t *)&ibm_apci_table_attr.size = ibm_get_table_from_acpi(NULL); ++ pax_close_kernel(); + retval = sysfs_create_bin_file(sysdir, &ibm_apci_table_attr); + + return retval; diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c index a6a71c4..c91097b 100644 --- a/drivers/pci/hotplug/cpcihp_generic.c @@ -38583,6 +40135,80 @@ index 76ba8a1..20ca857 100644 dbg("int15 entry = %p\n", compaq_int15_entry_point); /* initialize our int15 lock */ +diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c +index 202f4a9..8ee47d0 100644 +--- a/drivers/pci/hotplug/pci_hotplug_core.c ++++ b/drivers/pci/hotplug/pci_hotplug_core.c +@@ -448,8 +448,10 @@ int __pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, + return -EINVAL; + } + +- slot->ops->owner = owner; +- slot->ops->mod_name = mod_name; ++ pax_open_kernel(); ++ *(struct module **)&slot->ops->owner = owner; ++ *(const char **)&slot->ops->mod_name = mod_name; ++ pax_close_kernel(); + + mutex_lock(&pci_hp_mutex); + /* +diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c +index 939bd1d..a1459c9 100644 +--- a/drivers/pci/hotplug/pciehp_core.c ++++ b/drivers/pci/hotplug/pciehp_core.c +@@ -91,7 +91,7 @@ static int init_slot(struct controller *ctrl) + struct slot *slot = ctrl->slot; + struct hotplug_slot *hotplug = NULL; + struct hotplug_slot_info *info = NULL; +- struct hotplug_slot_ops *ops = NULL; ++ hotplug_slot_ops_no_const *ops = NULL; + char name[SLOT_NAME_SIZE]; + int retval = -ENOMEM; + +diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c +index 9c6e9bb..2916736 100644 +--- a/drivers/pci/pci-sysfs.c ++++ b/drivers/pci/pci-sysfs.c +@@ -1071,7 +1071,7 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine) + { + /* allocate attribute structure, piggyback attribute name */ + int name_len = write_combine ? 13 : 10; +- struct bin_attribute *res_attr; ++ bin_attribute_no_const *res_attr; + int retval; + + res_attr = kzalloc(sizeof(*res_attr) + name_len, GFP_ATOMIC); +@@ -1256,7 +1256,7 @@ static struct device_attribute reset_attr = __ATTR(reset, 0200, NULL, reset_stor + static int pci_create_capabilities_sysfs(struct pci_dev *dev) + { + int retval; +- struct bin_attribute *attr; ++ bin_attribute_no_const *attr; + + /* If the device has VPD, try to expose it in sysfs. */ + if (dev->vpd) { +@@ -1303,7 +1303,7 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) + { + int retval; + int rom_size = 0; +- struct bin_attribute *attr; ++ bin_attribute_no_const *attr; + + if (!sysfs_initialized) + return -EACCES; +diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h +index e851829..a1a7196 100644 +--- a/drivers/pci/pci.h ++++ b/drivers/pci/pci.h +@@ -98,7 +98,7 @@ struct pci_vpd_ops { + struct pci_vpd { + unsigned int len; + const struct pci_vpd_ops *ops; +- struct bin_attribute *attr; /* descriptor for sysfs VPD entry */ ++ bin_attribute_no_const *attr; /* descriptor for sysfs VPD entry */ + }; + + extern int pci_vpd_pci22_init(struct pci_dev *dev); diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 8474b6a..ee81993 100644 --- a/drivers/pci/pcie/aspm.c @@ -38634,6 +40260,44 @@ index 9b8505c..f00870a 100644 proc_create("devices", 0, proc_bus_pci_dir, &proc_bus_pci_dev_operations); proc_initialized = 1; +diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c +index 2111dbb..79e434b 100644 +--- a/drivers/platform/x86/msi-laptop.c ++++ b/drivers/platform/x86/msi-laptop.c +@@ -820,12 +820,14 @@ static int __init load_scm_model_init(struct platform_device *sdev) + int result; + + /* allow userland write sysfs file */ +- dev_attr_bluetooth.store = store_bluetooth; +- dev_attr_wlan.store = store_wlan; +- dev_attr_threeg.store = store_threeg; +- dev_attr_bluetooth.attr.mode |= S_IWUSR; +- dev_attr_wlan.attr.mode |= S_IWUSR; +- dev_attr_threeg.attr.mode |= S_IWUSR; ++ pax_open_kernel(); ++ *(void **)&dev_attr_bluetooth.store = store_bluetooth; ++ *(void **)&dev_attr_wlan.store = store_wlan; ++ *(void **)&dev_attr_threeg.store = store_threeg; ++ *(umode_t *)&dev_attr_bluetooth.attr.mode |= S_IWUSR; ++ *(umode_t *)&dev_attr_wlan.attr.mode |= S_IWUSR; ++ *(umode_t *)&dev_attr_threeg.attr.mode |= S_IWUSR; ++ pax_close_kernel(); + + /* disable hardware control by fn key */ + result = ec_read(MSI_STANDARD_EC_SCM_LOAD_ADDRESS, &data); +diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c +index b8ad71f..3ec9bb4 100644 +--- a/drivers/platform/x86/sony-laptop.c ++++ b/drivers/platform/x86/sony-laptop.c +@@ -2356,7 +2356,7 @@ static void sony_nc_lid_resume_cleanup(struct platform_device *pd) + } + + /* High speed charging function */ +-static struct device_attribute *hsc_handle; ++static device_attribute_no_const *hsc_handle; + + static ssize_t sony_nc_highspeed_charging_store(struct device *dev, + struct device_attribute *attr, diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index f946ca7..f25c833 100644 --- a/drivers/platform/x86/thinkpad_acpi.c @@ -38873,6 +40537,73 @@ index 7df7c5f..bd48c47 100644 ret = usb_register_notifier(transceiver, &otg_nb); if (ret) { dev_err(dev, "failure to register otg notifier\n"); +diff --git a/drivers/power/power_supply.h b/drivers/power/power_supply.h +index cc439fd..8fa30df 100644 +--- a/drivers/power/power_supply.h ++++ b/drivers/power/power_supply.h +@@ -16,12 +16,12 @@ struct power_supply; + + #ifdef CONFIG_SYSFS + +-extern void power_supply_init_attrs(struct device_type *dev_type); ++extern void power_supply_init_attrs(void); + extern int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env); + + #else + +-static inline void power_supply_init_attrs(struct device_type *dev_type) {} ++static inline void power_supply_init_attrs(void) {} + #define power_supply_uevent NULL + + #endif /* CONFIG_SYSFS */ +diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c +index 8a7cfb3..493e0a2 100644 +--- a/drivers/power/power_supply_core.c ++++ b/drivers/power/power_supply_core.c +@@ -24,7 +24,10 @@ + struct class *power_supply_class; + EXPORT_SYMBOL_GPL(power_supply_class); + +-static struct device_type power_supply_dev_type; ++extern const struct attribute_group *power_supply_attr_groups[]; ++static struct device_type power_supply_dev_type = { ++ .groups = power_supply_attr_groups, ++}; + + static int __power_supply_changed_work(struct device *dev, void *data) + { +@@ -393,7 +396,6 @@ static int __init power_supply_class_init(void) + return PTR_ERR(power_supply_class); + + power_supply_class->dev_uevent = power_supply_uevent; +- power_supply_init_attrs(&power_supply_dev_type); + + return 0; + } +diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c +index 40fa3b7..d9c2e0e 100644 +--- a/drivers/power/power_supply_sysfs.c ++++ b/drivers/power/power_supply_sysfs.c +@@ -229,17 +229,15 @@ static struct attribute_group power_supply_attr_group = { + .is_visible = power_supply_attr_is_visible, + }; + +-static const struct attribute_group *power_supply_attr_groups[] = { ++const struct attribute_group *power_supply_attr_groups[] = { + &power_supply_attr_group, + NULL, + }; + +-void power_supply_init_attrs(struct device_type *dev_type) ++void power_supply_init_attrs(void) + { + int i; + +- dev_type->groups = power_supply_attr_groups; +- + for (i = 0; i < ARRAY_SIZE(power_supply_attrs); i++) + __power_supply_attrs[i] = &power_supply_attrs[i].attr; + } diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index 4d7c635..9860196 100644 --- a/drivers/regulator/max8660.c @@ -38928,6 +40659,21 @@ index 0d84b1f..c2da6ac 100644 mc13xxx_data = mc13xxx_parse_regulators_dt(pdev, mc13892_regulators, ARRAY_SIZE(mc13892_regulators)); +diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c +index 16630aa..6afc992 100644 +--- a/drivers/rtc/rtc-cmos.c ++++ b/drivers/rtc/rtc-cmos.c +@@ -724,7 +724,9 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) + hpet_rtc_timer_init(); + + /* export at least the first block of NVRAM */ +- nvram.size = address_space - NVRAM_OFFSET; ++ pax_open_kernel(); ++ *(size_t *)&nvram.size = address_space - NVRAM_OFFSET; ++ pax_close_kernel(); + retval = sysfs_create_bin_file(&dev->kobj, &nvram); + if (retval < 0) { + dev_dbg(dev, "can't create nvram file? %d\n", retval); diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 9a86b4b..3a383dc 100644 --- a/drivers/rtc/rtc-dev.c @@ -38949,19 +40695,34 @@ index 9a86b4b..3a383dc 100644 return rtc_set_time(rtc, &tm); case RTC_PIE_ON: -diff --git a/drivers/scsi/bfa/bfa.h b/drivers/scsi/bfa/bfa.h -index 4ad7e36..d004679 100644 ---- a/drivers/scsi/bfa/bfa.h -+++ b/drivers/scsi/bfa/bfa.h -@@ -196,7 +196,7 @@ struct bfa_hwif_s { - u32 *end); - int cpe_vec_q0; - int rme_vec_q0; --}; -+} __no_const; - typedef void (*bfa_cb_iocfc_t) (void *cbarg, enum bfa_status status); +diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c +index e0d0ba4..3c65868 100644 +--- a/drivers/rtc/rtc-ds1307.c ++++ b/drivers/rtc/rtc-ds1307.c +@@ -106,7 +106,7 @@ struct ds1307 { + u8 offset; /* register's offset */ + u8 regs[11]; + u16 nvram_offset; +- struct bin_attribute *nvram; ++ bin_attribute_no_const *nvram; + enum ds_type type; + unsigned long flags; + #define HAS_NVRAM 0 /* bit 0 == sysfs file active */ +diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c +index 130f29a..6179d03 100644 +--- a/drivers/rtc/rtc-m48t59.c ++++ b/drivers/rtc/rtc-m48t59.c +@@ -482,7 +482,9 @@ static int m48t59_rtc_probe(struct platform_device *pdev) + goto out; + } + +- m48t59_nvram_attr.size = pdata->offset; ++ pax_open_kernel(); ++ *(size_t *)&m48t59_nvram_attr.size = pdata->offset; ++ pax_close_kernel(); - struct bfa_faa_cbfn_s { + ret = sysfs_create_bin_file(&pdev->dev.kobj, &m48t59_nvram_attr); + if (ret) { diff --git a/drivers/scsi/bfa/bfa_fcpim.h b/drivers/scsi/bfa/bfa_fcpim.h index e693af6..2e525b6 100644 --- a/drivers/scsi/bfa/bfa_fcpim.h @@ -39912,6 +41673,19 @@ index 19ee901..6e8c2ef 100644 static u8 *buf; +diff --git a/drivers/staging/iio/iio_hwmon.c b/drivers/staging/iio/iio_hwmon.c +index c7a5f97..71ecd35 100644 +--- a/drivers/staging/iio/iio_hwmon.c ++++ b/drivers/staging/iio/iio_hwmon.c +@@ -72,7 +72,7 @@ static void iio_hwmon_free_attrs(struct iio_hwmon_state *st) + static int iio_hwmon_probe(struct platform_device *pdev) + { + struct iio_hwmon_state *st; +- struct sensor_device_attribute *a; ++ sensor_device_attribute_no_const *a; + int ret, i; + int in_i = 1, temp_i = 1, curr_i = 1; + enum iio_chan_type type; diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c index 34afc16..ffe44dd 100644 --- a/drivers/staging/octeon/ethernet-rx.c @@ -41986,6 +43760,19 @@ index 5f3bcd3..bfca43f 100644 usb_autopm_put_interface(serial->interface); error_get_interface: usb_serial_put(serial); +diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h +index 75f70f0..d467e1a 100644 +--- a/drivers/usb/storage/usb.h ++++ b/drivers/usb/storage/usb.h +@@ -63,7 +63,7 @@ struct us_unusual_dev { + __u8 useProtocol; + __u8 useTransport; + int (*initFunction)(struct us_data *); +-}; ++} __do_const; + + + /* Dynamic bitflag definitions (us->dflags): used in set_bit() etc. */ diff --git a/drivers/usb/wusbcore/wa-hc.h b/drivers/usb/wusbcore/wa-hc.h index d6bea3e..60b250e 100644 --- a/drivers/usb/wusbcore/wa-hc.h @@ -42034,6 +43821,79 @@ index 8c55011..eed4ae1a 100644 "AGP", "PCI", "PRO AGP", +diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c +index 4f27fdc..d3537e6 100644 +--- a/drivers/video/aty/atyfb_base.c ++++ b/drivers/video/aty/atyfb_base.c +@@ -1325,10 +1325,14 @@ static int atyfb_set_par(struct fb_info *info) + par->accel_flags = var->accel_flags; /* hack */ + + if (var->accel_flags) { +- info->fbops->fb_sync = atyfb_sync; ++ pax_open_kernel(); ++ *(void **)&info->fbops->fb_sync = atyfb_sync; ++ pax_close_kernel(); + info->flags &= ~FBINFO_HWACCEL_DISABLED; + } else { +- info->fbops->fb_sync = NULL; ++ pax_open_kernel(); ++ *(void **)&info->fbops->fb_sync = NULL; ++ pax_close_kernel(); + info->flags |= FBINFO_HWACCEL_DISABLED; + } + +diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c +index 95ec042..ae33e7a 100644 +--- a/drivers/video/aty/mach64_cursor.c ++++ b/drivers/video/aty/mach64_cursor.c +@@ -208,7 +208,9 @@ int aty_init_cursor(struct fb_info *info) + info->sprite.buf_align = 16; /* and 64 lines tall. */ + info->sprite.flags = FB_PIXMAP_IO; + +- info->fbops->fb_cursor = atyfb_cursor; ++ pax_open_kernel(); ++ *(void **)&info->fbops->fb_cursor = atyfb_cursor; ++ pax_close_kernel(); + + return 0; + } +diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c +index 6c5ed6b..b727c88 100644 +--- a/drivers/video/backlight/kb3886_bl.c ++++ b/drivers/video/backlight/kb3886_bl.c +@@ -78,7 +78,7 @@ static struct kb3886bl_machinfo *bl_machinfo; + static unsigned long kb3886bl_flags; + #define KB3886BL_SUSPENDED 0x01 + +-static struct dmi_system_id __initdata kb3886bl_device_table[] = { ++static const struct dmi_system_id __initconst kb3886bl_device_table[] = { + { + .ident = "Sahara Touch-iT", + .matches = { +diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c +index 88cad6b..dd746c7 100644 +--- a/drivers/video/fb_defio.c ++++ b/drivers/video/fb_defio.c +@@ -206,7 +206,9 @@ void fb_deferred_io_init(struct fb_info *info) + + BUG_ON(!fbdefio); + mutex_init(&fbdefio->lock); +- info->fbops->fb_mmap = fb_deferred_io_mmap; ++ pax_open_kernel(); ++ *(void **)&info->fbops->fb_mmap = fb_deferred_io_mmap; ++ pax_close_kernel(); + INIT_DELAYED_WORK(&info->deferred_work, fb_deferred_io_work); + INIT_LIST_HEAD(&fbdefio->pagelist); + if (fbdefio->delay == 0) /* set a default of 1 s */ +@@ -237,7 +239,7 @@ void fb_deferred_io_cleanup(struct fb_info *info) + page->mapping = NULL; + } + +- info->fbops->fb_mmap = NULL; ++ *(void **)&info->fbops->fb_mmap = NULL; + mutex_destroy(&fbdefio->lock); + } + EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup); diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c index 5c3960d..15cf8fc 100644 --- a/drivers/video/fbcmap.c @@ -44820,8 +46680,119 @@ index 3c14e43..eafa544 100644 +4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 +4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 +4 4 4 4 4 4 +diff --git a/drivers/video/mb862xx/mb862xxfb_accel.c b/drivers/video/mb862xx/mb862xxfb_accel.c +index fe92eed..106e085 100644 +--- a/drivers/video/mb862xx/mb862xxfb_accel.c ++++ b/drivers/video/mb862xx/mb862xxfb_accel.c +@@ -312,14 +312,18 @@ void mb862xxfb_init_accel(struct fb_info *info, int xres) + struct mb862xxfb_par *par = info->par; + + if (info->var.bits_per_pixel == 32) { +- info->fbops->fb_fillrect = cfb_fillrect; +- info->fbops->fb_copyarea = cfb_copyarea; +- info->fbops->fb_imageblit = cfb_imageblit; ++ pax_open_kernel(); ++ *(void **)&info->fbops->fb_fillrect = cfb_fillrect; ++ *(void **)&info->fbops->fb_copyarea = cfb_copyarea; ++ *(void **)&info->fbops->fb_imageblit = cfb_imageblit; ++ pax_close_kernel(); + } else { + outreg(disp, GC_L0EM, 3); +- info->fbops->fb_fillrect = mb86290fb_fillrect; +- info->fbops->fb_copyarea = mb86290fb_copyarea; +- info->fbops->fb_imageblit = mb86290fb_imageblit; ++ pax_open_kernel(); ++ *(void **)&info->fbops->fb_fillrect = mb86290fb_fillrect; ++ *(void **)&info->fbops->fb_copyarea = mb86290fb_copyarea; ++ *(void **)&info->fbops->fb_imageblit = mb86290fb_imageblit; ++ pax_close_kernel(); + } + outreg(draw, GDC_REG_DRAW_BASE, 0); + outreg(draw, GDC_REG_MODE_MISC, 0x8000); +diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c +index ff22871..b129bed 100644 +--- a/drivers/video/nvidia/nvidia.c ++++ b/drivers/video/nvidia/nvidia.c +@@ -669,19 +669,23 @@ static int nvidiafb_set_par(struct fb_info *info) + info->fix.line_length = (info->var.xres_virtual * + info->var.bits_per_pixel) >> 3; + if (info->var.accel_flags) { +- info->fbops->fb_imageblit = nvidiafb_imageblit; +- info->fbops->fb_fillrect = nvidiafb_fillrect; +- info->fbops->fb_copyarea = nvidiafb_copyarea; +- info->fbops->fb_sync = nvidiafb_sync; ++ pax_open_kernel(); ++ *(void **)&info->fbops->fb_imageblit = nvidiafb_imageblit; ++ *(void **)&info->fbops->fb_fillrect = nvidiafb_fillrect; ++ *(void **)&info->fbops->fb_copyarea = nvidiafb_copyarea; ++ *(void **)&info->fbops->fb_sync = nvidiafb_sync; ++ pax_close_kernel(); + info->pixmap.scan_align = 4; + info->flags &= ~FBINFO_HWACCEL_DISABLED; + info->flags |= FBINFO_READS_FAST; + NVResetGraphics(info); + } else { +- info->fbops->fb_imageblit = cfb_imageblit; +- info->fbops->fb_fillrect = cfb_fillrect; +- info->fbops->fb_copyarea = cfb_copyarea; +- info->fbops->fb_sync = NULL; ++ pax_open_kernel(); ++ *(void **)&info->fbops->fb_imageblit = cfb_imageblit; ++ *(void **)&info->fbops->fb_fillrect = cfb_fillrect; ++ *(void **)&info->fbops->fb_copyarea = cfb_copyarea; ++ *(void **)&info->fbops->fb_sync = NULL; ++ pax_close_kernel(); + info->pixmap.scan_align = 1; + info->flags |= FBINFO_HWACCEL_DISABLED; + info->flags &= ~FBINFO_READS_FAST; +@@ -1173,8 +1177,11 @@ static int nvidia_set_fbinfo(struct fb_info *info) + info->pixmap.size = 8 * 1024; + info->pixmap.flags = FB_PIXMAP_SYSTEM; + +- if (!hwcur) +- info->fbops->fb_cursor = NULL; ++ if (!hwcur) { ++ pax_open_kernel(); ++ *(void **)&info->fbops->fb_cursor = NULL; ++ pax_close_kernel(); ++ } + + info->var.accel_flags = (!noaccel); + +diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c +index 76d9053..dec2bfd 100644 +--- a/drivers/video/s1d13xxxfb.c ++++ b/drivers/video/s1d13xxxfb.c +@@ -881,8 +881,10 @@ static int s1d13xxxfb_probe(struct platform_device *pdev) + + switch(prod_id) { + case S1D13506_PROD_ID: /* activate acceleration */ +- s1d13xxxfb_fbops.fb_fillrect = s1d13xxxfb_bitblt_solidfill; +- s1d13xxxfb_fbops.fb_copyarea = s1d13xxxfb_bitblt_copyarea; ++ pax_open_kernel(); ++ *(void **)&s1d13xxxfb_fbops.fb_fillrect = s1d13xxxfb_bitblt_solidfill; ++ *(void **)&s1d13xxxfb_fbops.fb_copyarea = s1d13xxxfb_bitblt_copyarea; ++ pax_close_kernel(); + info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN | + FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_COPYAREA; + break; +diff --git a/drivers/video/smscufx.c b/drivers/video/smscufx.c +index 97bd662..39fab85 100644 +--- a/drivers/video/smscufx.c ++++ b/drivers/video/smscufx.c +@@ -1171,7 +1171,9 @@ static int ufx_ops_release(struct fb_info *info, int user) + fb_deferred_io_cleanup(info); + kfree(info->fbdefio); + info->fbdefio = NULL; +- info->fbops->fb_mmap = ufx_ops_mmap; ++ pax_open_kernel(); ++ *(void **)&info->fbops->fb_mmap = ufx_ops_mmap; ++ pax_close_kernel(); + } + + pr_debug("released /dev/fb%d user=%d count=%d", diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c -index 86d449e..af6a7f7 100644 +index 86d449e..8e04dc5 100644 --- a/drivers/video/udlfb.c +++ b/drivers/video/udlfb.c @@ -619,11 +619,11 @@ int dlfb_handle_damage(struct dlfb_data *dev, int x, int y, @@ -44856,7 +46827,18 @@ index 86d449e..af6a7f7 100644 >> 10)), /* Kcycles */ &dev->cpu_kcycles_used); } -@@ -1372,7 +1372,7 @@ static ssize_t metrics_bytes_rendered_show(struct device *fbdev, +@@ -989,7 +989,9 @@ static int dlfb_ops_release(struct fb_info *info, int user) + fb_deferred_io_cleanup(info); + kfree(info->fbdefio); + info->fbdefio = NULL; +- info->fbops->fb_mmap = dlfb_ops_mmap; ++ pax_open_kernel(); ++ *(void **)&info->fbops->fb_mmap = dlfb_ops_mmap; ++ pax_close_kernel(); + } + + pr_warn("released /dev/fb%d user=%d count=%d\n", +@@ -1372,7 +1374,7 @@ static ssize_t metrics_bytes_rendered_show(struct device *fbdev, struct fb_info *fb_info = dev_get_drvdata(fbdev); struct dlfb_data *dev = fb_info->par; return snprintf(buf, PAGE_SIZE, "%u\n", @@ -44865,7 +46847,7 @@ index 86d449e..af6a7f7 100644 } static ssize_t metrics_bytes_identical_show(struct device *fbdev, -@@ -1380,7 +1380,7 @@ static ssize_t metrics_bytes_identical_show(struct device *fbdev, +@@ -1380,7 +1382,7 @@ static ssize_t metrics_bytes_identical_show(struct device *fbdev, struct fb_info *fb_info = dev_get_drvdata(fbdev); struct dlfb_data *dev = fb_info->par; return snprintf(buf, PAGE_SIZE, "%u\n", @@ -44874,7 +46856,7 @@ index 86d449e..af6a7f7 100644 } static ssize_t metrics_bytes_sent_show(struct device *fbdev, -@@ -1388,7 +1388,7 @@ static ssize_t metrics_bytes_sent_show(struct device *fbdev, +@@ -1388,7 +1390,7 @@ static ssize_t metrics_bytes_sent_show(struct device *fbdev, struct fb_info *fb_info = dev_get_drvdata(fbdev); struct dlfb_data *dev = fb_info->par; return snprintf(buf, PAGE_SIZE, "%u\n", @@ -44883,7 +46865,7 @@ index 86d449e..af6a7f7 100644 } static ssize_t metrics_cpu_kcycles_used_show(struct device *fbdev, -@@ -1396,7 +1396,7 @@ static ssize_t metrics_cpu_kcycles_used_show(struct device *fbdev, +@@ -1396,7 +1398,7 @@ static ssize_t metrics_cpu_kcycles_used_show(struct device *fbdev, struct fb_info *fb_info = dev_get_drvdata(fbdev); struct dlfb_data *dev = fb_info->par; return snprintf(buf, PAGE_SIZE, "%u\n", @@ -44892,7 +46874,7 @@ index 86d449e..af6a7f7 100644 } static ssize_t edid_show( -@@ -1456,10 +1456,10 @@ static ssize_t metrics_reset_store(struct device *fbdev, +@@ -1456,10 +1458,10 @@ static ssize_t metrics_reset_store(struct device *fbdev, struct fb_info *fb_info = dev_get_drvdata(fbdev); struct dlfb_data *dev = fb_info->par; @@ -44908,7 +46890,7 @@ index 86d449e..af6a7f7 100644 return count; } diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c -index b75db01..5631c6d 100644 +index b75db01..ad2f34a 100644 --- a/drivers/video/uvesafb.c +++ b/drivers/video/uvesafb.c @@ -19,6 +19,7 @@ @@ -44969,7 +46951,35 @@ index b75db01..5631c6d 100644 } #else /* The protected mode interface is not available on non-x86. */ -@@ -1836,6 +1860,11 @@ out: +@@ -1457,8 +1481,11 @@ static void uvesafb_init_info(struct fb_info *info, struct vbe_mode_ib *mode) + info->fix.ywrapstep = (par->ypan > 1) ? 1 : 0; + + /* Disable blanking if the user requested so. */ +- if (!blank) +- info->fbops->fb_blank = NULL; ++ if (!blank) { ++ pax_open_kernel(); ++ *(void **)&info->fbops->fb_blank = NULL; ++ pax_close_kernel(); ++ } + + /* + * Find out how much IO memory is required for the mode with +@@ -1534,8 +1561,11 @@ static void uvesafb_init_info(struct fb_info *info, struct vbe_mode_ib *mode) + info->flags = FBINFO_FLAG_DEFAULT | + (par->ypan ? FBINFO_HWACCEL_YPAN : 0); + +- if (!par->ypan) +- info->fbops->fb_pan_display = NULL; ++ if (!par->ypan) { ++ pax_open_kernel(); ++ *(void **)&info->fbops->fb_pan_display = NULL; ++ pax_close_kernel(); ++ } + } + + static void uvesafb_init_mtrr(struct fb_info *info) +@@ -1836,6 +1866,11 @@ out: if (par->vbe_modes) kfree(par->vbe_modes); @@ -44981,7 +46991,7 @@ index b75db01..5631c6d 100644 framebuffer_release(info); return err; } -@@ -1862,6 +1891,12 @@ static int uvesafb_remove(struct platform_device *dev) +@@ -1862,6 +1897,12 @@ static int uvesafb_remove(struct platform_device *dev) kfree(par->vbe_state_orig); if (par->vbe_state_saved) kfree(par->vbe_state_saved); @@ -44995,7 +47005,7 @@ index b75db01..5631c6d 100644 framebuffer_release(info); diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c -index 501b340..86bd4cf 100644 +index 501b340..d80aa17 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/vesafb.c @@ -9,6 +9,7 @@ @@ -45088,7 +47098,21 @@ index 501b340..86bd4cf 100644 printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal); if (pmi_base[3]) { printk(KERN_INFO "vesafb: pmi: ports = "); -@@ -488,6 +514,11 @@ static int __init vesafb_probe(struct platform_device *dev) +@@ -472,8 +498,11 @@ static int __init vesafb_probe(struct platform_device *dev) + info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE | + (ypan ? FBINFO_HWACCEL_YPAN : 0); + +- if (!ypan) +- info->fbops->fb_pan_display = NULL; ++ if (!ypan) { ++ pax_open_kernel(); ++ *(void **)&info->fbops->fb_pan_display = NULL; ++ pax_close_kernel(); ++ } + + if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { + err = -ENOMEM; +@@ -488,6 +517,11 @@ static int __init vesafb_probe(struct platform_device *dev) info->node, info->fix.id); return 0; err: @@ -47058,9 +49082,18 @@ index 958ae0e..505c9d0 100644 return hit; diff --git a/fs/compat.c b/fs/compat.c -index 015e1e1..5ce8e54 100644 +index 015e1e1..b8966ac 100644 --- a/fs/compat.c +++ b/fs/compat.c +@@ -54,7 +54,7 @@ + #include <asm/ioctls.h> + #include "internal.h" + +-int compat_log = 1; ++int compat_log = 0; + + int compat_printk(const char *fmt, ...) + { @@ -490,7 +490,7 @@ compat_sys_io_setup(unsigned nr_reqs, u32 __user *ctx32p) set_fs(KERNEL_DS); @@ -47469,7 +49502,7 @@ index b2a34a1..162fa69 100644 return rc; } diff --git a/fs/exec.c b/fs/exec.c -index 20df02c..5af5d91 100644 +index 20df02c..9b8f78d 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -55,6 +55,17 @@ @@ -47509,6 +49542,26 @@ index 20df02c..5af5d91 100644 int suid_dumpable = 0; static LIST_HEAD(formats); +@@ -75,8 +98,8 @@ void __register_binfmt(struct linux_binfmt * fmt, int insert) + { + BUG_ON(!fmt); + write_lock(&binfmt_lock); +- insert ? list_add(&fmt->lh, &formats) : +- list_add_tail(&fmt->lh, &formats); ++ insert ? pax_list_add((struct list_head *)&fmt->lh, &formats) : ++ pax_list_add_tail((struct list_head *)&fmt->lh, &formats); + write_unlock(&binfmt_lock); + } + +@@ -85,7 +108,7 @@ EXPORT_SYMBOL(__register_binfmt); + void unregister_binfmt(struct linux_binfmt * fmt) + { + write_lock(&binfmt_lock); +- list_del(&fmt->lh); ++ pax_list_del((struct list_head *)&fmt->lh); + write_unlock(&binfmt_lock); + } + @@ -180,18 +203,10 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, int write) { @@ -48386,6 +50439,19 @@ index 061727a..7622abf 100644 trace_ext4_mballoc_discard(sb, NULL, group, bit, pa->pa_len); return 0; +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 0465f36..99a003a 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2429,7 +2429,7 @@ struct ext4_attr { + ssize_t (*store)(struct ext4_attr *, struct ext4_sb_info *, + const char *, size_t); + int offset; +-}; ++} __do_const; + + static int parse_strtoul(const char *buf, + unsigned long max, unsigned long *value) diff --git a/fs/fcntl.c b/fs/fcntl.c index 71a600a..20d87b1 100644 --- a/fs/fcntl.c @@ -50176,9 +52242,27 @@ index a6597d6..41b30ec 100644 /* diff --git a/fs/jfs/super.c b/fs/jfs/super.c -index 1a543be..d803c40 100644 +index 1a543be..a4e1363 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c +@@ -225,7 +225,7 @@ static const match_table_t tokens = { + static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, + int *flag) + { +- void *nls_map = (void *)-1; /* -1: no change; NULL: none */ ++ const void *nls_map = (const void *)-1; /* -1: no change; NULL: none */ + char *p; + struct jfs_sb_info *sbi = JFS_SBI(sb); + +@@ -253,7 +253,7 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, + /* Don't do anything ;-) */ + break; + case Opt_iocharset: +- if (nls_map && nls_map != (void *) -1) ++ if (nls_map && nls_map != (const void *) -1) + unload_nls(nls_map); + if (!strcmp(args[0].from, "none")) + nls_map = NULL; @@ -855,7 +855,7 @@ static int __init init_jfs_fs(void) jfs_inode_cachep = @@ -50931,6 +53015,19 @@ index a51054f..f9b53e5 100644 return -EINVAL; get_mnt_ns(mnt_ns); +diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c +index 59461c9..b17c57e 100644 +--- a/fs/nfs/callback_xdr.c ++++ b/fs/nfs/callback_xdr.c +@@ -51,7 +51,7 @@ struct callback_op { + callback_decode_arg_t decode_args; + callback_encode_res_t encode_res; + long res_maxsize; +-}; ++} __do_const; + + static struct callback_op callback_ops[]; + diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index ebeb94c..ff35337 100644 --- a/fs/nfs/inode.c @@ -50955,6 +53052,50 @@ index ebeb94c..ff35337 100644 } void nfs_fattr_init(struct nfs_fattr *fattr) +diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c +index 9d1c5db..1e13db8 100644 +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -1097,7 +1097,7 @@ struct nfsd4_operation { + nfsd4op_rsize op_rsize_bop; + stateid_getter op_get_currentstateid; + stateid_setter op_set_currentstateid; +-}; ++} __do_const; + + static struct nfsd4_operation nfsd4_ops[]; + +diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c +index 0dc1158..ccf0338 100644 +--- a/fs/nfsd/nfs4xdr.c ++++ b/fs/nfsd/nfs4xdr.c +@@ -1456,7 +1456,7 @@ nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, void *p) + + typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *); + +-static nfsd4_dec nfsd4_dec_ops[] = { ++static const nfsd4_dec nfsd4_dec_ops[] = { + [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access, + [OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close, + [OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit, +@@ -1496,7 +1496,7 @@ static nfsd4_dec nfsd4_dec_ops[] = { + [OP_RELEASE_LOCKOWNER] = (nfsd4_dec)nfsd4_decode_release_lockowner, + }; + +-static nfsd4_dec nfsd41_dec_ops[] = { ++static const nfsd4_dec nfsd41_dec_ops[] = { + [OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access, + [OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close, + [OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit, +@@ -1558,7 +1558,7 @@ static nfsd4_dec nfsd41_dec_ops[] = { + }; + + struct nfsd4_minorversion_ops { +- nfsd4_dec *decoders; ++ const nfsd4_dec *decoders; + int nops; + }; + diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index d586117..143d568 100644 --- a/fs/nfsd/vfs.c @@ -50986,6 +53127,89 @@ index d586117..143d568 100644 set_fs(oldfs); if (host_err < 0) +diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c +index fea6bd5..8ee9d81 100644 +--- a/fs/nls/nls_base.c ++++ b/fs/nls/nls_base.c +@@ -234,20 +234,22 @@ EXPORT_SYMBOL(utf16s_to_utf8s); + + int register_nls(struct nls_table * nls) + { +- struct nls_table ** tmp = &tables; ++ struct nls_table *tmp = tables; + + if (nls->next) + return -EBUSY; + + spin_lock(&nls_lock); +- while (*tmp) { +- if (nls == *tmp) { ++ while (tmp) { ++ if (nls == tmp) { + spin_unlock(&nls_lock); + return -EBUSY; + } +- tmp = &(*tmp)->next; ++ tmp = tmp->next; + } +- nls->next = tables; ++ pax_open_kernel(); ++ *(struct nls_table **)&nls->next = tables; ++ pax_close_kernel(); + tables = nls; + spin_unlock(&nls_lock); + return 0; +@@ -255,12 +257,14 @@ int register_nls(struct nls_table * nls) + + int unregister_nls(struct nls_table * nls) + { +- struct nls_table ** tmp = &tables; ++ struct nls_table * const * tmp = &tables; + + spin_lock(&nls_lock); + while (*tmp) { + if (nls == *tmp) { +- *tmp = nls->next; ++ pax_open_kernel(); ++ *(struct nls_table **)tmp = nls->next; ++ pax_close_kernel(); + spin_unlock(&nls_lock); + return 0; + } +diff --git a/fs/nls/nls_euc-jp.c b/fs/nls/nls_euc-jp.c +index 7424929..35f6be5 100644 +--- a/fs/nls/nls_euc-jp.c ++++ b/fs/nls/nls_euc-jp.c +@@ -561,8 +561,10 @@ static int __init init_nls_euc_jp(void) + p_nls = load_nls("cp932"); + + if (p_nls) { +- table.charset2upper = p_nls->charset2upper; +- table.charset2lower = p_nls->charset2lower; ++ pax_open_kernel(); ++ *(const unsigned char **)&table.charset2upper = p_nls->charset2upper; ++ *(const unsigned char **)&table.charset2lower = p_nls->charset2lower; ++ pax_close_kernel(); + return register_nls(&table); + } + +diff --git a/fs/nls/nls_koi8-ru.c b/fs/nls/nls_koi8-ru.c +index e7bc1d7..06bd4bb 100644 +--- a/fs/nls/nls_koi8-ru.c ++++ b/fs/nls/nls_koi8-ru.c +@@ -63,8 +63,10 @@ static int __init init_nls_koi8_ru(void) + p_nls = load_nls("koi8-u"); + + if (p_nls) { +- table.charset2upper = p_nls->charset2upper; +- table.charset2lower = p_nls->charset2lower; ++ pax_open_kernel(); ++ *(const unsigned char **)&table.charset2upper = p_nls->charset2upper; ++ *(const unsigned char **)&table.charset2lower = p_nls->charset2lower; ++ pax_close_kernel(); + return register_nls(&table); + } + diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 9ff4a5e..deb1f0f 100644 --- a/fs/notify/fanotify/fanotify_user.c @@ -52256,7 +54480,7 @@ index fe72cd0..21b52ff 100644 rcu_read_lock(); task = pid_task(proc_pid(dir), PIDTYPE_PID); diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c -index 1827d88..9a60b01 100644 +index 1827d88..43b0279 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -12,11 +12,15 @@ @@ -52373,6 +54597,75 @@ index 1827d88..9a60b01 100644 .lookup = proc_sys_lookup, .permission = proc_sys_permission, .setattr = proc_sys_setattr, +@@ -854,7 +887,7 @@ static struct ctl_dir *find_subdir(struct ctl_dir *dir, + static struct ctl_dir *new_dir(struct ctl_table_set *set, + const char *name, int namelen) + { +- struct ctl_table *table; ++ ctl_table_no_const *table; + struct ctl_dir *new; + struct ctl_node *node; + char *new_name; +@@ -866,7 +899,7 @@ static struct ctl_dir *new_dir(struct ctl_table_set *set, + return NULL; + + node = (struct ctl_node *)(new + 1); +- table = (struct ctl_table *)(node + 1); ++ table = (ctl_table_no_const *)(node + 1); + new_name = (char *)(table + 2); + memcpy(new_name, name, namelen); + new_name[namelen] = '\0'; +@@ -1035,7 +1068,8 @@ static int sysctl_check_table(const char *path, struct ctl_table *table) + static struct ctl_table_header *new_links(struct ctl_dir *dir, struct ctl_table *table, + struct ctl_table_root *link_root) + { +- struct ctl_table *link_table, *entry, *link; ++ ctl_table_no_const *link_table, *link; ++ struct ctl_table *entry; + struct ctl_table_header *links; + struct ctl_node *node; + char *link_name; +@@ -1058,7 +1092,7 @@ static struct ctl_table_header *new_links(struct ctl_dir *dir, struct ctl_table + return NULL; + + node = (struct ctl_node *)(links + 1); +- link_table = (struct ctl_table *)(node + nr_entries); ++ link_table = (ctl_table_no_const *)(node + nr_entries); + link_name = (char *)&link_table[nr_entries + 1]; + + for (link = link_table, entry = table; entry->procname; link++, entry++) { +@@ -1306,8 +1340,8 @@ static int register_leaf_sysctl_tables(const char *path, char *pos, + struct ctl_table_header ***subheader, struct ctl_table_set *set, + struct ctl_table *table) + { +- struct ctl_table *ctl_table_arg = NULL; +- struct ctl_table *entry, *files; ++ ctl_table_no_const *ctl_table_arg = NULL, *files = NULL; ++ struct ctl_table *entry; + int nr_files = 0; + int nr_dirs = 0; + int err = -ENOMEM; +@@ -1319,10 +1353,9 @@ static int register_leaf_sysctl_tables(const char *path, char *pos, + nr_files++; + } + +- files = table; + /* If there are mixed files and directories we need a new table */ + if (nr_dirs && nr_files) { +- struct ctl_table *new; ++ ctl_table_no_const *new; + files = kzalloc(sizeof(struct ctl_table) * (nr_files + 1), + GFP_KERNEL); + if (!files) +@@ -1340,7 +1373,7 @@ static int register_leaf_sysctl_tables(const char *path, char *pos, + /* Register everything except a directory full of subdirectories */ + if (nr_files || !nr_dirs) { + struct ctl_table_header *header; +- header = __register_sysctl_table(set, path, files); ++ header = __register_sysctl_table(set, path, files ? files : table); + if (!header) { + kfree(ctl_table_arg); + goto out; diff --git a/fs/proc/root.c b/fs/proc/root.c index c6e9fac..a740964 100644 --- a/fs/proc/root.c @@ -54400,7 +56693,7 @@ index 0000000..1b9afa9 +endif diff --git a/grsecurity/gracl.c b/grsecurity/gracl.c new file mode 100644 -index 0000000..6b7b8f7 +index 0000000..0767b2e --- /dev/null +++ b/grsecurity/gracl.c @@ -0,0 +1,4067 @@ @@ -56994,7 +59287,7 @@ index 0000000..6b7b8f7 + task->is_writable = 1; + +#ifdef CONFIG_GRKERNSEC_RBAC_DEBUG -+ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename); ++ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task_pid_nr(task), task->role->rolename, task->acl->filename); +#endif + + gr_set_proc_res(task); @@ -57069,7 +59362,7 @@ index 0000000..6b7b8f7 + gr_set_proc_res(task); + +#ifdef CONFIG_GRKERNSEC_RBAC_DEBUG -+ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename); ++ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task_pid_nr(task), task->role->rolename, task->acl->filename); +#endif + return 0; +} @@ -57483,7 +59776,7 @@ index 0000000..6b7b8f7 + tsk->is_writable = 1; + +#ifdef CONFIG_GRKERNSEC_RBAC_DEBUG -+ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid); ++ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, task_pid_nr(tsk)); +#endif + +out_unlock: @@ -57537,7 +59830,7 @@ index 0000000..6b7b8f7 + if (file && S_ISCHR(file->f_path.dentry->d_inode->i_mode) && + file->f_path.dentry->d_inode->i_rdev == our_file->f_path.dentry->d_inode->i_rdev) { + p3 = task; -+ while (p3->pid > 0) { ++ while (task_pid_nr(p3) > 0) { + if (p3 == p) + break; + p3 = p3->real_parent; @@ -57628,7 +59921,7 @@ index 0000000..6b7b8f7 + + if (gr_usermode->mode != GR_SPROLE && gr_usermode->mode != GR_STATUS && + gr_usermode->mode != GR_UNSPROLE && gr_usermode->mode != GR_SPROLEPAM && -+ !uid_eq(current_uid(), GLOBAL_ROOT_UID)) { ++ gr_is_global_nonroot(current_uid())) { + error = -EPERM; + goto out; + } @@ -57867,7 +60160,7 @@ index 0000000..6b7b8f7 + gr_set_proc_res(task); + +#ifdef CONFIG_GRKERNSEC_RBAC_DEBUG -+ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename); ++ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task_pid_nr(task), task->role->rolename, task->acl->filename); +#endif + } else { + return 1; @@ -57908,7 +60201,7 @@ index 0000000..6b7b8f7 + read_unlock(&grsec_exec_file_lock); + read_unlock(&tasklist_lock); + rcu_read_unlock(); -+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid); ++ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task_pid_nr(task)); + return ret; + } + } else { @@ -58056,13 +60349,13 @@ index 0000000..6b7b8f7 + read_lock(&grsec_exec_file_lock); + filp = task->exec_file; + -+ while (tmp->pid > 0) { ++ while (task_pid_nr(tmp) > 0) { + if (tmp == curtemp) + break; + tmp = tmp->real_parent; + } + -+ if (!filp || (tmp->pid == 0 && ((grsec_enable_harden_ptrace && !uid_eq(current_uid(), GLOBAL_ROOT_UID) && !(gr_status & GR_READY)) || ++ if (!filp || (task_pid_nr(tmp) == 0 && ((grsec_enable_harden_ptrace && gr_is_global_nonroot(current_uid()) && !(gr_status & GR_READY)) || + ((gr_status & GR_READY) && !(current->acl->mode & GR_RELAXPTRACE))))) { + read_unlock(&grsec_exec_file_lock); + read_unlock(&tasklist_lock); @@ -58086,7 +60379,7 @@ index 0000000..6b7b8f7 + + if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD) + && (current->acl != task->acl || (current->acl != current->role->root_label -+ && current->pid != task->pid))) ++ && task_pid_nr(current) != task_pid_nr(task)))) + return 1; + + return 0; @@ -58118,13 +60411,13 @@ index 0000000..6b7b8f7 +#endif + if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) { + read_lock(&tasklist_lock); -+ while (tmp->pid > 0) { ++ while (task_pid_nr(tmp) > 0) { + if (tmp == curtemp) + break; + tmp = tmp->real_parent; + } + -+ if (tmp->pid == 0 && ((grsec_enable_harden_ptrace && !uid_eq(current_uid(), GLOBAL_ROOT_UID) && !(gr_status & GR_READY)) || ++ if (task_pid_nr(tmp) == 0 && ((grsec_enable_harden_ptrace && gr_is_global_nonroot(current_uid()) && !(gr_status & GR_READY)) || + ((gr_status & GR_READY) && !(current->acl->mode & GR_RELAXPTRACE)))) { + read_unlock(&tasklist_lock); + gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task); @@ -58336,10 +60629,10 @@ index 0000000..6b7b8f7 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP) + cred = __task_cred(task); +#ifdef CONFIG_GRKERNSEC_PROC_USER -+ if (!uid_eq(cred->uid, GLOBAL_ROOT_UID)) ++ if (gr_is_global_nonroot(cred->uid)) + ret = -EACCES; +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP) -+ if (!uid_eq(cred->uid, GLOBAL_ROOT_UID) && !groups_search(cred->group_info, grsec_proc_gid)) ++ if (gr_is_global_nonroot(cred->uid) && !groups_search(cred->group_info, grsec_proc_gid)) + ret = -EACCES; +#endif +#endif @@ -59814,7 +62107,7 @@ index 0000000..39645c9 +} diff --git a/grsecurity/gracl_segv.c b/grsecurity/gracl_segv.c new file mode 100644 -index 0000000..10398db +index 0000000..8c8fc9d --- /dev/null +++ b/grsecurity/gracl_segv.c @@ -0,0 +1,303 @@ @@ -60032,7 +62325,7 @@ index 0000000..10398db + time_after(curr->expires, get_seconds())) { + rcu_read_lock(); + cred = __task_cred(task); -+ if (!uid_eq(cred->uid, GLOBAL_ROOT_UID) && proc_is_setxid(cred)) { ++ if (gr_is_global_nonroot(cred->uid) && proc_is_setxid(cred)) { + gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max); + spin_lock(&gr_uid_lock); + gr_insert_uid(cred->uid, curr->expires); @@ -60123,7 +62416,7 @@ index 0000000..10398db +} diff --git a/grsecurity/gracl_shm.c b/grsecurity/gracl_shm.c new file mode 100644 -index 0000000..120978a +index 0000000..98011b0 --- /dev/null +++ b/grsecurity/gracl_shm.c @@ -0,0 +1,40 @@ @@ -60154,7 +62447,7 @@ index 0000000..120978a + task = find_task_by_vpid(shm_lapid); + + if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) || -+ (task->pid == shm_lapid)) && ++ (task_pid_nr(task) == shm_lapid)) && + (task->acl->mode & GR_PROTSHM) && + (task->acl != current->acl))) { + read_unlock(&tasklist_lock); @@ -60194,7 +62487,7 @@ index 0000000..bc0be01 +} diff --git a/grsecurity/grsec_chroot.c b/grsecurity/grsec_chroot.c new file mode 100644 -index 0000000..70fe0ae +index 0000000..6d2de57 --- /dev/null +++ b/grsecurity/grsec_chroot.c @@ -0,0 +1,357 @@ @@ -60212,7 +62505,7 @@ index 0000000..70fe0ae +void gr_set_chroot_entries(struct task_struct *task, struct path *path) +{ +#ifdef CONFIG_GRKERNSEC -+ if (task->pid > 1 && path->dentry != init_task.fs->root.dentry && ++ if (task_pid_nr(task) > 1 && path->dentry != init_task.fs->root.dentry && + path->dentry != task->nsproxy->mnt_ns->root->mnt.mnt_root) + task->gr_is_chrooted = 1; + else @@ -60277,7 +62570,7 @@ index 0000000..70fe0ae +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE + if (grsec_enable_chroot_nice && (niceval < task_nice(p)) + && proc_is_chrooted(current)) { -+ gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid); ++ gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, task_pid_nr(p)); + return -EACCES; + } +#endif @@ -61525,7 +63818,7 @@ index 0000000..a862e9f +} diff --git a/grsecurity/grsec_link.c b/grsecurity/grsec_link.c new file mode 100644 -index 0000000..6095407 +index 0000000..5e05e20 --- /dev/null +++ b/grsecurity/grsec_link.c @@ -0,0 +1,58 @@ @@ -61542,7 +63835,7 @@ index 0000000..6095407 + + if (grsec_enable_symlinkown && in_group_p(grsec_symlinkown_gid) && + /* ignore root-owned links, e.g. /proc/self */ -+ !uid_eq(link_inode->i_uid, GLOBAL_ROOT_UID) && target && ++ gr_is_global_nonroot(link_inode->i_uid) && target && + !uid_eq(link_inode->i_uid, target->i_uid)) { + gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINKOWNER_MSG, link->dentry, link->mnt, link_inode->i_uid, target->i_uid); + return 1; @@ -61580,7 +63873,7 @@ index 0000000..6095407 + if (grsec_enable_link && !uid_eq(cred->fsuid, inode->i_uid) && + (!S_ISREG(mode) || is_privileged_binary(dentry) || + (inode_permission(inode, MAY_READ | MAY_WRITE))) && -+ !capable(CAP_FOWNER) && !uid_eq(cred->uid, GLOBAL_ROOT_UID)) { ++ !capable(CAP_FOWNER) && gr_is_global_nonroot(cred->uid)) { + gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to->name); + return -EPERM; + } @@ -62113,7 +64406,7 @@ index 0000000..f7f29aa +} diff --git a/grsecurity/grsec_sig.c b/grsecurity/grsec_sig.c new file mode 100644 -index 0000000..5c00416 +index 0000000..e09715a --- /dev/null +++ b/grsecurity/grsec_sig.c @@ -0,0 +1,222 @@ @@ -62137,7 +64430,7 @@ index 0000000..5c00416 +#ifdef CONFIG_GRKERNSEC_SIGNAL + if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) || + (sig == SIGABRT) || (sig == SIGBUS))) { -+ if (t->pid == current->pid) { ++ if (task_pid_nr(t) == task_pid_nr(current)) { + gr_log_sig_addr(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, signames[sig], addr); + } else { + gr_log_sig_task(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig); @@ -62152,7 +64445,7 @@ index 0000000..5c00416 +{ +#ifdef CONFIG_GRKERNSEC + /* ignore the 0 signal for protected task checks */ -+ if (current->pid > 1 && sig && gr_check_protected_task(p)) { ++ if (task_pid_nr(current) > 1 && sig && gr_check_protected_task(p)) { + gr_log_sig_task(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig); + return -EPERM; + } else if (gr_pid_is_chrooted((struct task_struct *)p)) { @@ -62226,7 +64519,7 @@ index 0000000..5c00416 + const struct cred *cred = __task_cred(p), *cred2; + struct task_struct *tsk, *tsk2; + -+ if (!__get_dumpable(mm_flags) && !uid_eq(cred->uid, GLOBAL_ROOT_UID)) { ++ if (!__get_dumpable(mm_flags) && gr_is_global_nonroot(cred->uid)) { + struct user_struct *user; + + uid = cred->uid; @@ -62252,9 +64545,9 @@ index 0000000..5c00416 + read_unlock(&tasklist_lock); + rcu_read_unlock(); + -+ if (!uid_eq(uid, GLOBAL_ROOT_UID)) ++ if (gr_is_global_nonroot(uid)) + printk(KERN_ALERT "grsec: bruteforce prevention initiated against uid %u, banning for %d minutes\n", -+ from_kuid_munged(&init_user_ns, uid), GR_USER_BAN_TIME / 60); ++ GR_GLOBAL_UID(uid), GR_USER_BAN_TIME / 60); + else if (daemon) + gr_log_noargs(GR_DONT_AUDIT, GR_BRUTE_DAEMON_MSG); + @@ -62290,7 +64583,7 @@ index 0000000..5c00416 + + uid = current_uid(); + -+ if (uid_eq(uid, GLOBAL_ROOT_UID)) ++ if (gr_is_global_root(uid)) + panic("grsec: halting the system due to suspicious kernel crash caused by root"); + else { + /* kill all the processes of this user, hold a reference @@ -62298,7 +64591,7 @@ index 0000000..5c00416 + another process until system reset + */ + printk(KERN_ALERT "grsec: banning user with uid %u until system restart for suspicious kernel crash\n", -+ from_kuid_munged(&init_user_ns, uid)); ++ GR_GLOBAL_UID(uid)); + /* we intentionally leak this ref */ + user = get_uid(current->cred->user); + if (user) { @@ -63088,7 +65381,7 @@ index 0000000..0dc13c3 +EXPORT_SYMBOL(gr_log_timechange); diff --git a/grsecurity/grsec_tpe.c b/grsecurity/grsec_tpe.c new file mode 100644 -index 0000000..ac20d7f +index 0000000..ee57dcf --- /dev/null +++ b/grsecurity/grsec_tpe.c @@ -0,0 +1,73 @@ @@ -63110,7 +65403,7 @@ index 0000000..ac20d7f + char *msg2 = NULL; + + // never restrict root -+ if (uid_eq(cred->uid, GLOBAL_ROOT_UID)) ++ if (gr_is_global_root(cred->uid)) + return 1; + + if (grsec_enable_tpe) { @@ -63131,7 +65424,7 @@ index 0000000..ac20d7f + if (!msg) + goto next_check; + -+ if (!uid_eq(inode->i_uid, GLOBAL_ROOT_UID)) ++ if (gr_is_global_nonroot(inode->i_uid)) + msg2 = "file in non-root-owned directory"; + else if (inode->i_mode & S_IWOTH) + msg2 = "file in world-writable directory"; @@ -63150,7 +65443,7 @@ index 0000000..ac20d7f + if (!grsec_enable_tpe || !grsec_enable_tpe_all) + return 1; + -+ if (!uid_eq(inode->i_uid, GLOBAL_ROOT_UID) && !uid_eq(inode->i_uid, cred->uid)) ++ if (gr_is_global_nonroot(inode->i_uid) && !uid_eq(inode->i_uid, cred->uid)) + msg = "directory not owned by user"; + else if (inode->i_mode & S_IWOTH) + msg = "file in world-writable directory"; @@ -63868,7 +66161,7 @@ index 418d270..bfd2794 100644 struct crypto_instance { struct crypto_alg alg; diff --git a/include/drm/drmP.h b/include/drm/drmP.h -index fad21c9..3fff955 100644 +index fad21c9..ab858bc 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -72,6 +72,7 @@ @@ -63879,7 +66172,43 @@ index fad21c9..3fff955 100644 #include <drm/drm.h> #include <drm/drm_sarea.h> -@@ -1068,7 +1069,7 @@ struct drm_device { +@@ -293,10 +294,12 @@ do { \ + * \param cmd command. + * \param arg argument. + */ +-typedef int drm_ioctl_t(struct drm_device *dev, void *data, ++typedef int (* const drm_ioctl_t)(struct drm_device *dev, void *data, ++ struct drm_file *file_priv); ++typedef int (* drm_ioctl_no_const_t)(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +-typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, ++typedef int (* const drm_ioctl_compat_t)(struct file *filp, unsigned int cmd, + unsigned long arg); + + #define DRM_IOCTL_NR(n) _IOC_NR(n) +@@ -311,9 +314,9 @@ typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, + struct drm_ioctl_desc { + unsigned int cmd; + int flags; +- drm_ioctl_t *func; ++ drm_ioctl_t func; + unsigned int cmd_drv; +-}; ++} __do_const; + + /** + * Creates a driver or general drm_ioctl_desc array entry for the given +@@ -995,7 +998,7 @@ struct drm_info_list { + int (*show)(struct seq_file*, void*); /** show callback */ + u32 driver_features; /**< Required driver features for this entry */ + void *data; +-}; ++} __do_const; + + /** + * debugfs node structure. This structure represents a debugfs file. +@@ -1068,7 +1071,7 @@ struct drm_device { /** \name Usage Counters */ /*@{ */ @@ -63888,7 +66217,7 @@ index fad21c9..3fff955 100644 atomic_t ioctl_count; /**< Outstanding IOCTLs pending */ atomic_t vma_count; /**< Outstanding vma areas open */ int buf_use; /**< Buffers in use -- cannot alloc */ -@@ -1079,7 +1080,7 @@ struct drm_device { +@@ -1079,7 +1082,7 @@ struct drm_device { /*@{ */ unsigned long counters; enum drm_stat_type types[15]; @@ -63923,8 +66252,21 @@ index 72dcbe8..8db58d7 100644 /** * struct ttm_mem_global - Global memory accounting structure. +diff --git a/include/keys/asymmetric-subtype.h b/include/keys/asymmetric-subtype.h +index 4b840e8..155d235 100644 +--- a/include/keys/asymmetric-subtype.h ++++ b/include/keys/asymmetric-subtype.h +@@ -37,7 +37,7 @@ struct asymmetric_key_subtype { + /* Verify the signature on a key of this subtype (optional) */ + int (*verify_signature)(const struct key *key, + const struct public_key_signature *sig); +-}; ++} __do_const; + + /** + * asymmetric_key_subtype - Get the subtype from an asymmetric key diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h -index c1da539..4db35ec 100644 +index c1da539..1dcec55 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h @@ -28,7 +28,7 @@ struct compat_atm_iobuf { @@ -63936,17 +66278,29 @@ index c1da539..4db35ec 100644 __AAL_STAT_ITEMS #undef __HANDLE_ITEM }; +@@ -200,7 +200,7 @@ struct atmdev_ops { /* only send is required */ + int (*change_qos)(struct atm_vcc *vcc,struct atm_qos *qos,int flags); + int (*proc_read)(struct atm_dev *dev,loff_t *pos,char *page); + struct module *owner; +-}; ++} __do_const ; + + struct atmphy_ops { + int (*start)(struct atm_dev *dev); diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h -index 0530b98..b127a9e 100644 +index 0530b98..96a8ac0 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h -@@ -73,6 +73,7 @@ struct linux_binfmt { +@@ -73,8 +73,9 @@ struct linux_binfmt { int (*load_binary)(struct linux_binprm *); int (*load_shlib)(struct file *); int (*core_dump)(struct coredump_params *cprm); + void (*handle_mprotect)(struct vm_area_struct *vma, unsigned long newflags); unsigned long min_coredump; /* minimal dump size */ - }; +-}; ++} __do_const; + + extern void __register_binfmt(struct linux_binfmt *fmt, int insert); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index f94bc83..62b9cfe 100644 @@ -64207,6 +66561,19 @@ index dd852b7..72924c0 100644 +#define ACCESS_ONCE_RW(x) (*(volatile typeof(x) *)&(x)) #endif /* __LINUX_COMPILER_H */ +diff --git a/include/linux/configfs.h b/include/linux/configfs.h +index 34025df..d94bbbc 100644 +--- a/include/linux/configfs.h ++++ b/include/linux/configfs.h +@@ -125,7 +125,7 @@ struct configfs_attribute { + const char *ca_name; + struct module *ca_owner; + umode_t ca_mode; +-}; ++} __do_const; + + /* + * Users often need to create attribute structures for their configurable diff --git a/include/linux/cpu.h b/include/linux/cpu.h index ce7a074..01ab8ac 100644 --- a/include/linux/cpu.h @@ -64220,6 +66587,50 @@ index ce7a074..01ab8ac 100644 { .notifier_call = fn, .priority = pri }; \ register_cpu_notifier(&fn##_nb); \ } +diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h +index a55b88e..fba90c5 100644 +--- a/include/linux/cpufreq.h ++++ b/include/linux/cpufreq.h +@@ -240,7 +240,7 @@ struct cpufreq_driver { + int (*suspend) (struct cpufreq_policy *policy); + int (*resume) (struct cpufreq_policy *policy); + struct freq_attr **attr; +-}; ++} __do_const; + + /* flags */ + +@@ -299,6 +299,7 @@ struct global_attr { + ssize_t (*store)(struct kobject *a, struct attribute *b, + const char *c, size_t count); + }; ++typedef struct global_attr __no_const global_attr_no_const; + + #define define_one_global_ro(_name) \ + static struct global_attr _name = \ +diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h +index 24cd1037..20a63aae 100644 +--- a/include/linux/cpuidle.h ++++ b/include/linux/cpuidle.h +@@ -54,7 +54,8 @@ struct cpuidle_state { + int index); + + int (*enter_dead) (struct cpuidle_device *dev, int index); +-}; ++} __do_const; ++typedef struct cpuidle_state __no_const cpuidle_state_no_const; + + /* Idle State Flags */ + #define CPUIDLE_FLAG_TIME_VALID (0x01) /* is residency time measurable? */ +@@ -216,7 +217,7 @@ struct cpuidle_governor { + void (*reflect) (struct cpuidle_device *dev, int index); + + struct module *owner; +-}; ++} __do_const; + + #ifdef CONFIG_CPU_IDLE + diff --git a/include/linux/cred.h b/include/linux/cred.h index 04421e8..6bce4ef 100644 --- a/include/linux/cred.h @@ -64276,6 +66687,55 @@ index 7925bf0..d5143d2 100644 #define free(a) kfree(a) #define large_malloc(a) vmalloc(a) +diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h +index e83ef39..33e0eb3 100644 +--- a/include/linux/devfreq.h ++++ b/include/linux/devfreq.h +@@ -114,7 +114,7 @@ struct devfreq_governor { + int (*get_target_freq)(struct devfreq *this, unsigned long *freq); + int (*event_handler)(struct devfreq *devfreq, + unsigned int event, void *data); +-}; ++} __do_const; + + /** + * struct devfreq - Device devfreq structure +diff --git a/include/linux/device.h b/include/linux/device.h +index 43dcda9..7a1fb65 100644 +--- a/include/linux/device.h ++++ b/include/linux/device.h +@@ -294,7 +294,7 @@ struct subsys_interface { + struct list_head node; + int (*add_dev)(struct device *dev, struct subsys_interface *sif); + int (*remove_dev)(struct device *dev, struct subsys_interface *sif); +-}; ++} __do_const; + + int subsys_interface_register(struct subsys_interface *sif); + void subsys_interface_unregister(struct subsys_interface *sif); +@@ -474,7 +474,7 @@ struct device_type { + void (*release)(struct device *dev); + + const struct dev_pm_ops *pm; +-}; ++} __do_const; + + /* interface for exporting device attributes */ + struct device_attribute { +@@ -484,11 +484,12 @@ struct device_attribute { + ssize_t (*store)(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count); + }; ++typedef struct device_attribute __no_const device_attribute_no_const; + + struct dev_ext_attribute { + struct device_attribute attr; + void *var; +-}; ++} __do_const; + + ssize_t device_show_ulong(struct device *dev, struct device_attribute *attr, + char *buf); diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 94af418..b1ca7a2 100644 --- a/include/linux/dma-mapping.h @@ -64337,6 +66797,32 @@ index 8c9048e..16a4665 100644 #endif +diff --git a/include/linux/extcon.h b/include/linux/extcon.h +index fcb51c8..bdafcf6 100644 +--- a/include/linux/extcon.h ++++ b/include/linux/extcon.h +@@ -134,7 +134,7 @@ struct extcon_dev { + /* /sys/class/extcon/.../mutually_exclusive/... */ + struct attribute_group attr_g_muex; + struct attribute **attrs_muex; +- struct device_attribute *d_attrs_muex; ++ device_attribute_no_const *d_attrs_muex; + }; + + /** +diff --git a/include/linux/fb.h b/include/linux/fb.h +index c7a9571..02eeffe 100644 +--- a/include/linux/fb.h ++++ b/include/linux/fb.h +@@ -302,7 +302,7 @@ struct fb_ops { + /* called at KDB enter and leave time to prepare the console */ + int (*fb_debug_enter)(struct fb_info *info); + int (*fb_debug_leave)(struct fb_info *info); +-}; ++} __do_const; + + #ifdef CONFIG_FB_TILEBLITTING + #define FB_TILE_CURSOR_NONE 0 diff --git a/include/linux/filter.h b/include/linux/filter.h index c45eabc..baa0be5 100644 --- a/include/linux/filter.h @@ -64436,6 +66922,19 @@ index 5dfa0aa..6acf322 100644 op->processor = processor; op->release = release; INIT_LIST_HEAD(&op->pend_link); +diff --git a/include/linux/fscache.h b/include/linux/fscache.h +index 7a08623..4c07b0f 100644 +--- a/include/linux/fscache.h ++++ b/include/linux/fscache.h +@@ -152,7 +152,7 @@ struct fscache_cookie_def { + * - this is mandatory for any object that may have data + */ + void (*now_uncached)(void *cookie_netfs_data); +-}; ++} __do_const; + + /* + * fscache cached network filesystem type diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 0fbfb46..508eb0d 100644 --- a/include/linux/fsnotify.h @@ -64495,6 +66994,19 @@ index 79b8bba..86b539e 100644 struct disk_events *ev; #ifdef CONFIG_BLK_DEV_INTEGRITY struct blk_integrity *integrity; +diff --git a/include/linux/genl_magic_func.h b/include/linux/genl_magic_func.h +index 023bc34..b02b46a 100644 +--- a/include/linux/genl_magic_func.h ++++ b/include/linux/genl_magic_func.h +@@ -246,7 +246,7 @@ const char *CONCAT_(GENL_MAGIC_FAMILY, _genl_cmd_to_str)(__u8 cmd) + }, + + #define ZZZ_genl_ops CONCAT_(GENL_MAGIC_FAMILY, _genl_ops) +-static struct genl_ops ZZZ_genl_ops[] __read_mostly = { ++static struct genl_ops ZZZ_genl_ops[] = { + #include GENL_MAGIC_INCLUDE_FILE + }; + diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 0f615eb..5c3832f 100644 --- a/include/linux/gfp.h @@ -65674,6 +68186,29 @@ index ef788b5..ac41b7b 100644 static inline void zero_user_segments(struct page *page, unsigned start1, unsigned end1, unsigned start2, unsigned end2) +diff --git a/include/linux/hwmon-sysfs.h b/include/linux/hwmon-sysfs.h +index 1c7b89a..7f52502 100644 +--- a/include/linux/hwmon-sysfs.h ++++ b/include/linux/hwmon-sysfs.h +@@ -25,7 +25,8 @@ + struct sensor_device_attribute{ + struct device_attribute dev_attr; + int index; +-}; ++} __do_const; ++typedef struct sensor_device_attribute __no_const sensor_device_attribute_no_const; + #define to_sensor_dev_attr(_dev_attr) \ + container_of(_dev_attr, struct sensor_device_attribute, dev_attr) + +@@ -41,7 +42,7 @@ struct sensor_device_attribute_2 { + struct device_attribute dev_attr; + u8 index; + u8 nr; +-}; ++} __do_const; + #define to_sensor_dev_attr_2(_dev_attr) \ + container_of(_dev_attr, struct sensor_device_attribute_2, dev_attr) + diff --git a/include/linux/i2c.h b/include/linux/i2c.h index d0c4db7..61b3577 100644 --- a/include/linux/i2c.h @@ -65826,6 +68361,33 @@ index 5fa5afe..ac55b25 100644 extern void softirq_init(void); extern void __raise_softirq_irqoff(unsigned int nr); +diff --git a/include/linux/iommu.h b/include/linux/iommu.h +index f3b99e1..9b73cee 100644 +--- a/include/linux/iommu.h ++++ b/include/linux/iommu.h +@@ -101,7 +101,7 @@ struct iommu_ops { + int (*domain_set_attr)(struct iommu_domain *domain, + enum iommu_attr attr, void *data); + unsigned long pgsize_bitmap; +-}; ++} __do_const; + + #define IOMMU_GROUP_NOTIFY_ADD_DEVICE 1 /* Device added */ + #define IOMMU_GROUP_NOTIFY_DEL_DEVICE 2 /* Pre Device removed */ +diff --git a/include/linux/irq.h b/include/linux/irq.h +index fdf2c4a..5332486 100644 +--- a/include/linux/irq.h ++++ b/include/linux/irq.h +@@ -328,7 +328,8 @@ struct irq_chip { + void (*irq_print_chip)(struct irq_data *data, struct seq_file *p); + + unsigned long flags; +-}; ++} __do_const; ++typedef struct irq_chip __no_const irq_chip_no_const; + + /* + * irq_chip specific flags diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h index 6883e19..06992b1 100644 --- a/include/linux/kallsyms.h @@ -65858,6 +68420,19 @@ index 6883e19..06992b1 100644 /* This macro allows us to keep printk typechecking */ static __printf(1, 2) +diff --git a/include/linux/key-type.h b/include/linux/key-type.h +index 518a53a..5e28358 100644 +--- a/include/linux/key-type.h ++++ b/include/linux/key-type.h +@@ -125,7 +125,7 @@ struct key_type { + /* internal fields */ + struct list_head link; /* link in types list */ + struct lock_class_key lock_class; /* key->sem lock class */ +-}; ++} __do_const; + + extern struct key_type key_type_keyring; + diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index 4dff0c6..1ca9b72 100644 --- a/include/linux/kgdb.h @@ -65903,7 +68478,7 @@ index 5398d58..5883a34 100644 #define request_module_nowait(mod...) __request_module(false, mod) #define try_then_request_module(x, mod...) \ diff --git a/include/linux/kobject.h b/include/linux/kobject.h -index 939b112..90b7f44 100644 +index 939b112..ed6ed51 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -111,7 +111,7 @@ struct kobj_type { @@ -65915,6 +68490,27 @@ index 939b112..90b7f44 100644 struct kobj_uevent_env { char *envp[UEVENT_NUM_ENVP]; +@@ -134,6 +134,7 @@ struct kobj_attribute { + ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count); + }; ++typedef struct kobj_attribute __no_const kobj_attribute_no_const; + + extern const struct sysfs_ops kobj_sysfs_ops; + +diff --git a/include/linux/kobject_ns.h b/include/linux/kobject_ns.h +index f66b065..c2c29b4 100644 +--- a/include/linux/kobject_ns.h ++++ b/include/linux/kobject_ns.h +@@ -43,7 +43,7 @@ struct kobj_ns_type_operations { + const void *(*netlink_ns)(struct sock *sk); + const void *(*initial_ns)(void); + void (*drop_ns)(void *); +-}; ++} __do_const; + + int kobj_ns_type_register(const struct kobj_ns_type_operations *ops); + int kobj_ns_type_registered(enum kobj_ns_type type); diff --git a/include/linux/kref.h b/include/linux/kref.h index 4972e6e..de4d19b 100644 --- a/include/linux/kref.h @@ -65964,19 +68560,38 @@ index 649e5f8..ead5194 100644 struct ata_port_info { unsigned long flags; diff --git a/include/linux/list.h b/include/linux/list.h -index cc6d2aa..71febca 100644 +index cc6d2aa..c10ee83 100644 --- a/include/linux/list.h +++ b/include/linux/list.h -@@ -112,6 +112,9 @@ extern void __list_del_entry(struct list_head *entry); +@@ -112,6 +112,19 @@ extern void __list_del_entry(struct list_head *entry); extern void list_del(struct list_head *entry); #endif -+extern void pax_list_add_tail(struct list_head *new, struct list_head *head); ++extern void __pax_list_add(struct list_head *new, ++ struct list_head *prev, ++ struct list_head *next); ++static inline void pax_list_add(struct list_head *new, struct list_head *head) ++{ ++ __pax_list_add(new, head, head->next); ++} ++static inline void pax_list_add_tail(struct list_head *new, struct list_head *head) ++{ ++ __pax_list_add(new, head->prev, head); ++} +extern void pax_list_del(struct list_head *entry); + /** * list_replace - replace old entry by new one * @old : the element to be replaced +@@ -145,6 +158,8 @@ static inline void list_del_init(struct list_head *entry) + INIT_LIST_HEAD(entry); + } + ++extern void pax_list_del_init(struct list_head *entry); ++ + /** + * list_move - delete from one list and add as another's head + * @list: the entry to move diff --git a/include/linux/mm.h b/include/linux/mm.h index 66e2f7c..ea88001 100644 --- a/include/linux/mm.h @@ -66247,7 +68862,7 @@ index 73b64a3..6562925 100644 /* * The target ratio of ACTIVE_ANON to INACTIVE_ANON pages on diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h -index fed3def..7cc3f93 100644 +index fed3def..c933f99 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -12,7 +12,7 @@ @@ -66268,8 +68883,17 @@ index fed3def..7cc3f93 100644 #define HID_BUS_ANY 0xffff #define HID_GROUP_ANY 0x0000 +@@ -498,7 +498,7 @@ struct dmi_system_id { + const char *ident; + struct dmi_strmatch matches[4]; + void *driver_data; +-}; ++} __do_const; + /* + * struct dmi_device_id appears during expansion of + * "MODULE_DEVICE_TABLE(dmi, x)". Compiler doesn't look inside it diff --git a/include/linux/module.h b/include/linux/module.h -index 1375ee3..d631af0 100644 +index 1375ee3..ced8177 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -17,9 +17,11 @@ @@ -66284,7 +68908,31 @@ index 1375ee3..d631af0 100644 /* In stripped ARM and x86-64 modules, ~ is surprisingly rare. */ #define MODULE_SIG_STRING "~Module signature appended~\n" -@@ -281,19 +283,16 @@ struct module +@@ -54,12 +56,13 @@ struct module_attribute { + int (*test)(struct module *); + void (*free)(struct module *); + }; ++typedef struct module_attribute __no_const module_attribute_no_const; + + struct module_version_attribute { + struct module_attribute mattr; + const char *module_name; + const char *version; +-} __attribute__ ((__aligned__(sizeof(void *)))); ++} __do_const __attribute__ ((__aligned__(sizeof(void *)))); + + extern ssize_t __modver_version_show(struct module_attribute *, + struct module_kobject *, char *); +@@ -232,7 +235,7 @@ struct module + + /* Sysfs stuff. */ + struct module_kobject mkobj; +- struct module_attribute *modinfo_attrs; ++ module_attribute_no_const *modinfo_attrs; + const char *version; + const char *srcversion; + struct kobject *holders_dir; +@@ -281,19 +284,16 @@ struct module int (*init)(void); /* If this is non-NULL, vfree after init() returns */ @@ -66308,7 +68956,7 @@ index 1375ee3..d631af0 100644 /* Arch-specific module values */ struct mod_arch_specific arch; -@@ -349,6 +348,10 @@ struct module +@@ -349,6 +349,10 @@ struct module #ifdef CONFIG_EVENT_TRACING struct ftrace_event_call **trace_events; unsigned int num_trace_events; @@ -66319,7 +68967,7 @@ index 1375ee3..d631af0 100644 #endif #ifdef CONFIG_FTRACE_MCOUNT_RECORD unsigned int num_ftrace_callsites; -@@ -396,16 +399,46 @@ bool is_module_address(unsigned long addr); +@@ -396,16 +400,46 @@ bool is_module_address(unsigned long addr); bool is_module_percpu_address(unsigned long addr); bool is_module_text_address(unsigned long addr); @@ -66469,6 +69117,19 @@ index 5a5ff57..5ae5070 100644 { return nd->saved_names[nd->depth]; } +diff --git a/include/linux/net.h b/include/linux/net.h +index aa16731..514b875 100644 +--- a/include/linux/net.h ++++ b/include/linux/net.h +@@ -183,7 +183,7 @@ struct net_proto_family { + int (*create)(struct net *net, struct socket *sock, + int protocol, int kern); + struct module *owner; +-}; ++} __do_const; + + struct iovec; + struct kvec; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 9ef07d0..130a5d9 100644 --- a/include/linux/netdevice.h @@ -66490,6 +69151,19 @@ index 9ef07d0..130a5d9 100644 * Do not use this in drivers. */ +diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h +index ee14284..bc65d63 100644 +--- a/include/linux/netfilter.h ++++ b/include/linux/netfilter.h +@@ -82,7 +82,7 @@ struct nf_sockopt_ops { + #endif + /* Use the module struct to lock set/get code in place */ + struct module *owner; +-}; ++} __do_const; + + /* Function to register/unregister hook points. */ + int nf_register_hook(struct nf_hook_ops *reg); diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h index 7958e84..ed74d7a 100644 --- a/include/linux/netfilter/ipset/ip_set.h @@ -66531,6 +69205,19 @@ index 0000000..33f4af8 +}; + +#endif +diff --git a/include/linux/nls.h b/include/linux/nls.h +index 5dc635f..35f5e11 100644 +--- a/include/linux/nls.h ++++ b/include/linux/nls.h +@@ -31,7 +31,7 @@ struct nls_table { + const unsigned char *charset2upper; + struct module *owner; + struct nls_table *next; +-}; ++} __do_const; + + /* this value hold the maximum octet of charset */ + #define NLS_MAX_CHARSET_SIZE 6 /* for UTF-8 */ diff --git a/include/linux/notifier.h b/include/linux/notifier.h index d65746e..62e72c2 100644 --- a/include/linux/notifier.h @@ -66561,6 +69248,20 @@ index a4c5624..79d6d88 100644 /** create a directory */ struct dentry * oprofilefs_mkdir(struct super_block * sb, struct dentry * root, +diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h +index 45fc162..01a4068 100644 +--- a/include/linux/pci_hotplug.h ++++ b/include/linux/pci_hotplug.h +@@ -80,7 +80,8 @@ struct hotplug_slot_ops { + int (*get_attention_status) (struct hotplug_slot *slot, u8 *value); + int (*get_latch_status) (struct hotplug_slot *slot, u8 *value); + int (*get_adapter_status) (struct hotplug_slot *slot, u8 *value); +-}; ++} __do_const; ++typedef struct hotplug_slot_ops __no_const hotplug_slot_ops_no_const; + + /** + * struct hotplug_slot_info - used to notify the hotplug pci core of the state of the slot diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 6bfb2faa..e5bc5e5 100644 --- a/include/linux/perf_event.h @@ -66626,6 +69327,32 @@ index 5f28cae..3d23723 100644 extern void s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd); +diff --git a/include/linux/platform_data/usb-exynos.h b/include/linux/platform_data/usb-exynos.h +index c256c59..8ea94c7 100644 +--- a/include/linux/platform_data/usb-exynos.h ++++ b/include/linux/platform_data/usb-exynos.h +@@ -14,7 +14,7 @@ + struct exynos4_ohci_platdata { + int (*phy_init)(struct platform_device *pdev, int type); + int (*phy_exit)(struct platform_device *pdev, int type); +-}; ++} __no_const; + + extern void exynos4_ohci_set_platdata(struct exynos4_ohci_platdata *pd); + +diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h +index 7c1d252..c5c773e 100644 +--- a/include/linux/pm_domain.h ++++ b/include/linux/pm_domain.h +@@ -48,7 +48,7 @@ struct gpd_dev_ops { + + struct gpd_cpu_data { + unsigned int saved_exit_latency; +- struct cpuidle_state *idle_state; ++ cpuidle_state_no_const *idle_state; + }; + + struct generic_pm_domain { diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index f271860..6b3bec5 100644 --- a/include/linux/pm_runtime.h @@ -66639,6 +69366,19 @@ index f271860..6b3bec5 100644 } #else /* !CONFIG_PM_RUNTIME */ +diff --git a/include/linux/pnp.h b/include/linux/pnp.h +index 195aafc..49a7bc2 100644 +--- a/include/linux/pnp.h ++++ b/include/linux/pnp.h +@@ -297,7 +297,7 @@ static inline void pnp_set_drvdata(struct pnp_dev *pdev, void *data) + struct pnp_fixup { + char id[7]; + void (*quirk_function) (struct pnp_dev * dev); /* fixup function */ +-}; ++} __do_const; + + /* config parameters */ + #define PNP_CONFIG_NORMAL 0x0001 diff --git a/include/linux/poison.h b/include/linux/poison.h index 2110a81..13a11bb 100644 --- a/include/linux/poison.h @@ -66667,6 +69407,19 @@ index c0f44c2..1572583 100644 /** * struct omap_sr_nvalue_table - Smartreflex n-target value info +diff --git a/include/linux/ppp-comp.h b/include/linux/ppp-comp.h +index 4ea1d37..80f4b33 100644 +--- a/include/linux/ppp-comp.h ++++ b/include/linux/ppp-comp.h +@@ -84,7 +84,7 @@ struct compressor { + struct module *owner; + /* Extra skb space needed by the compressor algorithm */ + unsigned int comp_extra; +-}; ++} __do_const; + + /* + * The return value from decompress routine is the length of the diff --git a/include/linux/printk.h b/include/linux/printk.h index 9afc01e..92c32e8 100644 --- a/include/linux/printk.h @@ -66727,6 +69480,54 @@ index d984608..d6f0042 100644 /* * Handle minimum values for seeds */ +diff --git a/include/linux/rculist.h b/include/linux/rculist.h +index c92dd28..08f4eab 100644 +--- a/include/linux/rculist.h ++++ b/include/linux/rculist.h +@@ -44,6 +44,9 @@ extern void __list_add_rcu(struct list_head *new, + struct list_head *prev, struct list_head *next); + #endif + ++extern void __pax_list_add_rcu(struct list_head *new, ++ struct list_head *prev, struct list_head *next); ++ + /** + * list_add_rcu - add a new entry to rcu-protected list + * @new: new entry to be added +@@ -65,6 +68,11 @@ static inline void list_add_rcu(struct list_head *new, struct list_head *head) + __list_add_rcu(new, head, head->next); + } + ++static inline void pax_list_add_rcu(struct list_head *new, struct list_head *head) ++{ ++ __pax_list_add_rcu(new, head, head->next); ++} ++ + /** + * list_add_tail_rcu - add a new entry to rcu-protected list + * @new: new entry to be added +@@ -87,6 +95,12 @@ static inline void list_add_tail_rcu(struct list_head *new, + __list_add_rcu(new, head->prev, head); + } + ++static inline void pax_list_add_tail_rcu(struct list_head *new, ++ struct list_head *head) ++{ ++ __pax_list_add_rcu(new, head->prev, head); ++} ++ + /** + * list_del_rcu - deletes entry from list without re-initialization + * @entry: the element to delete from the list. +@@ -117,6 +131,8 @@ static inline void list_del_rcu(struct list_head *entry) + entry->prev = LIST_POISON2; + } + ++extern void pax_list_del_rcu(struct list_head *entry); ++ + /** + * hlist_del_init_rcu - deletes entry from hash list with re-initialization + * @n: the element to delete from the hash list. diff --git a/include/linux/reboot.h b/include/linux/reboot.h index 23b3630..e1bc12b 100644 --- a/include/linux/reboot.h @@ -66822,7 +69623,7 @@ index c20635c..2f5def4 100644 static inline void anon_vma_merge(struct vm_area_struct *vma, struct vm_area_struct *next) diff --git a/include/linux/sched.h b/include/linux/sched.h -index d211247..d64a165 100644 +index d211247..a5cbf38b 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -61,6 +61,7 @@ struct bio_list; @@ -66887,6 +69688,15 @@ index d211247..d64a165 100644 /* Hash table maintenance information */ struct hlist_node uidhash_node; kuid_t uid; +@@ -1116,7 +1146,7 @@ struct sched_class { + #ifdef CONFIG_FAIR_GROUP_SCHED + void (*task_move_group) (struct task_struct *p, int on_rq); + #endif +-}; ++} __do_const; + + struct load_weight { + unsigned long weight, inv_weight; @@ -1360,8 +1390,8 @@ struct task_struct { struct list_head thread_group; @@ -67018,6 +69828,15 @@ index d211247..d64a165 100644 /* Future-safe accessor for struct task_struct's cpus_allowed. */ #define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed) +@@ -1696,7 +1799,7 @@ struct pid_namespace; + pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type, + struct pid_namespace *ns); + +-static inline pid_t task_pid_nr(struct task_struct *tsk) ++static inline pid_t task_pid_nr(const struct task_struct *tsk) + { + return tsk->pid; + } @@ -2155,7 +2258,9 @@ void yield(void); extern struct exec_domain default_exec_domain; @@ -67405,6 +70224,19 @@ index 9db4825..ed42fb5 100644 void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); #ifdef CONFIG_TRACING +diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h +index e8d702e..0a56eb4 100644 +--- a/include/linux/sock_diag.h ++++ b/include/linux/sock_diag.h +@@ -10,7 +10,7 @@ struct sock; + struct sock_diag_handler { + __u8 family; + int (*dump)(struct sk_buff *skb, struct nlmsghdr *nlh); +-}; ++} __do_const; + + int sock_diag_register(const struct sock_diag_handler *h); + void sock_diag_unregister(const struct sock_diag_handler *h); diff --git a/include/linux/sonet.h b/include/linux/sonet.h index 680f9a3..f13aeb0 100644 --- a/include/linux/sonet.h @@ -67419,9 +70251,18 @@ index 680f9a3..f13aeb0 100644 #undef __HANDLE_ITEM }; diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h -index 34206b8..f019e06 100644 +index 34206b8..3db7f1c 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h +@@ -96,7 +96,7 @@ struct rpc_procinfo { + unsigned int p_timer; /* Which RTT timer to use */ + u32 p_statidx; /* Which procedure to account */ + const char * p_name; /* name of procedure */ +-}; ++} __do_const; + + #ifdef __KERNEL__ + @@ -176,9 +176,9 @@ static inline unsigned short rpc_get_port(const struct sockaddr *sap) { switch (sap->sa_family) { @@ -67452,6 +70293,19 @@ index 34206b8..f019e06 100644 } #endif /* __KERNEL__ */ +diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h +index 676ddf5..4c519a1 100644 +--- a/include/linux/sunrpc/svc.h ++++ b/include/linux/sunrpc/svc.h +@@ -410,7 +410,7 @@ struct svc_procedure { + unsigned int pc_count; /* call count */ + unsigned int pc_cachetype; /* cache info (NFS) */ + unsigned int pc_xdrressize; /* maximum size of XDR reply */ +-}; ++} __do_const; + + /* + * Function prototypes. diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h index 0b8e3e6..33e0a01 100644 --- a/include/linux/sunrpc/svc_rdma.h @@ -67481,11 +70335,58 @@ index 0b8e3e6..33e0a01 100644 #define RPCRDMA_VERSION 1 +diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h +index dd74084a..7f509d5 100644 +--- a/include/linux/sunrpc/svcauth.h ++++ b/include/linux/sunrpc/svcauth.h +@@ -109,7 +109,7 @@ struct auth_ops { + int (*release)(struct svc_rqst *rq); + void (*domain_release)(struct auth_domain *); + int (*set_client)(struct svc_rqst *rq); +-}; ++} __do_const; + + #define SVC_GARBAGE 1 + #define SVC_SYSERR 2 +diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h +index 071d62c..4ccc7ac 100644 +--- a/include/linux/swiotlb.h ++++ b/include/linux/swiotlb.h +@@ -59,7 +59,8 @@ extern void + + extern void + swiotlb_free_coherent(struct device *hwdev, size_t size, +- void *vaddr, dma_addr_t dma_handle); ++ void *vaddr, dma_addr_t dma_handle, ++ struct dma_attrs *attrs); + + extern dma_addr_t swiotlb_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, +diff --git a/include/linux/syscore_ops.h b/include/linux/syscore_ops.h +index 27b3b0b..e093dd9 100644 +--- a/include/linux/syscore_ops.h ++++ b/include/linux/syscore_ops.h +@@ -16,7 +16,7 @@ struct syscore_ops { + int (*suspend)(void); + void (*resume)(void); + void (*shutdown)(void); +-}; ++} __do_const; + + extern void register_syscore_ops(struct syscore_ops *ops); + extern void unregister_syscore_ops(struct syscore_ops *ops); diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h -index 14a8ff2..21fe4c7 100644 +index 14a8ff2..af52bad 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h -@@ -41,6 +41,8 @@ typedef int proc_handler (struct ctl_table *ctl, int write, +@@ -34,13 +34,13 @@ struct ctl_table_root; + struct ctl_table_header; + struct ctl_dir; + +-typedef struct ctl_table ctl_table; +- + typedef int proc_handler (struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos); extern int proc_dostring(struct ctl_table *, int, void __user *, size_t *, loff_t *); @@ -67494,19 +70395,67 @@ index 14a8ff2..21fe4c7 100644 extern int proc_dointvec(struct ctl_table *, int, void __user *, size_t *, loff_t *); extern int proc_dointvec_minmax(struct ctl_table *, int, +@@ -115,7 +115,9 @@ struct ctl_table + struct ctl_table_poll *poll; + void *extra1; + void *extra2; +-}; ++} __do_const; ++typedef struct ctl_table __no_const ctl_table_no_const; ++typedef struct ctl_table ctl_table; + + struct ctl_node { + struct rb_node node; +diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h +index 381f06d..dc16cc7 100644 +--- a/include/linux/sysfs.h ++++ b/include/linux/sysfs.h +@@ -31,7 +31,8 @@ struct attribute { + struct lock_class_key *key; + struct lock_class_key skey; + #endif +-}; ++} __do_const; ++typedef struct attribute __no_const attribute_no_const; + + /** + * sysfs_attr_init - initialize a dynamically allocated sysfs attribute +@@ -59,8 +60,8 @@ struct attribute_group { + umode_t (*is_visible)(struct kobject *, + struct attribute *, int); + struct attribute **attrs; +-}; +- ++} __do_const; ++typedef struct attribute_group __no_const attribute_group_no_const; + + + /** +@@ -107,7 +108,8 @@ struct bin_attribute { + char *, loff_t, size_t); + int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr, + struct vm_area_struct *vma); +-}; ++} __do_const; ++typedef struct bin_attribute __no_const bin_attribute_no_const; + + /** + * sysfs_bin_attr_init - initialize a dynamically allocated bin_attribute diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h -index 7faf933..c1ad32c 100644 +index 7faf933..4657127 100644 --- a/include/linux/sysrq.h +++ b/include/linux/sysrq.h -@@ -15,6 +15,7 @@ +@@ -15,7 +15,9 @@ #define _LINUX_SYSRQ_H #include <linux/errno.h> +#include <linux/compiler.h> #include <linux/types.h> ++#include <linux/compiler.h> /* Enable/disable SYSRQ support by default (0==no, 1==yes). */ -@@ -36,7 +37,7 @@ struct sysrq_key_op { + #define SYSRQ_DEFAULT_ENABLE 1 +@@ -36,7 +38,7 @@ struct sysrq_key_op { char *help_msg; char *action_msg; int enable_mask; @@ -67634,15 +70583,17 @@ index 5ca0951..ab496a5 100644 }) diff --git a/include/linux/uidgid.h b/include/linux/uidgid.h -index 8e522cbc..1b67af5 100644 +index 8e522cbc..aa8572d 100644 --- a/include/linux/uidgid.h +++ b/include/linux/uidgid.h -@@ -197,4 +197,7 @@ static inline bool kgid_has_mapping(struct user_namespace *ns, kgid_t gid) +@@ -197,4 +197,9 @@ static inline bool kgid_has_mapping(struct user_namespace *ns, kgid_t gid) #endif /* CONFIG_USER_NS */ +#define GR_GLOBAL_UID(x) from_kuid_munged(&init_user_ns, (x)) +#define GR_GLOBAL_GID(x) from_kgid_munged(&init_user_ns, (x)) ++#define gr_is_global_root(x) uid_eq((x), GLOBAL_ROOT_UID) ++#define gr_is_global_nonroot(x) (!uid_eq((x), GLOBAL_ROOT_UID)) + #endif /* _LINUX_UIDGID_H */ diff --git a/include/linux/unaligned/access_ok.h b/include/linux/unaligned/access_ok.h @@ -67894,6 +70845,19 @@ index a13291f..af51fa3 100644 } static inline void __dec_zone_page_state(struct page *page, +diff --git a/include/linux/xattr.h b/include/linux/xattr.h +index fdbafc6..b7ffd47 100644 +--- a/include/linux/xattr.h ++++ b/include/linux/xattr.h +@@ -28,7 +28,7 @@ struct xattr_handler { + size_t size, int handler_flags); + int (*set)(struct dentry *dentry, const char *name, const void *buffer, + size_t size, int flags, int handler_flags); +-}; ++} __do_const; + + struct xattr { + char *name; diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 95d1c91..6798cca 100644 --- a/include/media/v4l2-dev.h @@ -67919,6 +70883,32 @@ index 4118ad1..cb7e25f 100644 /* v4l debugging and diagnostics */ /* Debug bitmask flags to be used on V4L2 */ +diff --git a/include/net/9p/transport.h b/include/net/9p/transport.h +index adcbb20..62c2559 100644 +--- a/include/net/9p/transport.h ++++ b/include/net/9p/transport.h +@@ -57,7 +57,7 @@ struct p9_trans_module { + int (*cancel) (struct p9_client *, struct p9_req_t *req); + int (*zc_request)(struct p9_client *, struct p9_req_t *, + char *, char *, int , int, int, int); +-}; ++} __do_const; + + void v9fs_register_trans(struct p9_trans_module *m); + void v9fs_unregister_trans(struct p9_trans_module *m); +diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h +index 7588ef4..e62d35f 100644 +--- a/include/net/bluetooth/l2cap.h ++++ b/include/net/bluetooth/l2cap.h +@@ -552,7 +552,7 @@ struct l2cap_ops { + void (*defer) (struct l2cap_chan *chan); + struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan, + unsigned long len, int nb); +-}; ++} __do_const; + + struct l2cap_conn { + struct hci_conn *hcon; diff --git a/include/net/caif/cfctrl.h b/include/net/caif/cfctrl.h index 9e5425b..8136ffc 100644 --- a/include/net/caif/cfctrl.h @@ -67955,6 +70945,19 @@ index 628e11b..4c475df 100644 +extern atomic_unchecked_t flow_cache_genid; #endif +diff --git a/include/net/genetlink.h b/include/net/genetlink.h +index bdfbe68..4402ebe 100644 +--- a/include/net/genetlink.h ++++ b/include/net/genetlink.h +@@ -118,7 +118,7 @@ struct genl_ops { + struct netlink_callback *cb); + int (*done)(struct netlink_callback *cb); + struct list_head ops_list; +-}; ++} __do_const; + + extern int genl_register_family(struct genl_family *family); + extern int genl_register_family_with_ops(struct genl_family *family, diff --git a/include/net/gro_cells.h b/include/net/gro_cells.h index e5062c9..48a9a4b 100644 --- a/include/net/gro_cells.h @@ -68021,6 +71024,19 @@ index 53f464d..ba76aaa 100644 return new; } +diff --git a/include/net/ip.h b/include/net/ip.h +index a68f838..74518ab 100644 +--- a/include/net/ip.h ++++ b/include/net/ip.h +@@ -202,7 +202,7 @@ extern struct local_ports { + } sysctl_local_ports; + extern void inet_get_local_port_range(int *low, int *high); + +-extern unsigned long *sysctl_local_reserved_ports; ++extern unsigned long sysctl_local_reserved_ports[65536 / 8 / sizeof(unsigned long)]; + static inline int inet_is_reserved_local_port(int port) + { + return test_bit(port, sysctl_local_reserved_ports); diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 9497be1..5a4fafe 100644 --- a/include/net/ip_fib.h @@ -68035,7 +71051,7 @@ index 9497be1..5a4fafe 100644 fib_info_update_nh_saddr((net), &FIB_RES_NH(res))) #define FIB_RES_GW(res) (FIB_RES_NH(res).nh_gw) diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h -index 68c69d5..2ee192b 100644 +index 68c69d5..bdab192 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -599,7 +599,7 @@ struct ip_vs_conn { @@ -68056,6 +71072,20 @@ index 68c69d5..2ee192b 100644 atomic_t weight; /* server weight */ atomic_t refcnt; /* reference counter */ +@@ -980,11 +980,11 @@ struct netns_ipvs { + /* ip_vs_lblc */ + int sysctl_lblc_expiration; + struct ctl_table_header *lblc_ctl_header; +- struct ctl_table *lblc_ctl_table; ++ ctl_table_no_const *lblc_ctl_table; + /* ip_vs_lblcr */ + int sysctl_lblcr_expiration; + struct ctl_table_header *lblcr_ctl_header; +- struct ctl_table *lblcr_ctl_table; ++ ctl_table_no_const *lblcr_ctl_table; + /* ip_vs_est */ + struct list_head est_list; /* estimator list */ + spinlock_t est_lock; diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h index 80ffde3..968b0f4 100644 --- a/include/net/irda/ircomm_tty.h @@ -68081,6 +71111,86 @@ index cc7c197..9f2da2a 100644 }; unsigned int iucv_sock_poll(struct file *file, struct socket *sock, +diff --git a/include/net/llc_c_ac.h b/include/net/llc_c_ac.h +index df83f69..9b640b8 100644 +--- a/include/net/llc_c_ac.h ++++ b/include/net/llc_c_ac.h +@@ -87,7 +87,7 @@ + #define LLC_CONN_AC_STOP_SENDACK_TMR 70 + #define LLC_CONN_AC_START_SENDACK_TMR_IF_NOT_RUNNING 71 + +-typedef int (*llc_conn_action_t)(struct sock *sk, struct sk_buff *skb); ++typedef int (* const llc_conn_action_t)(struct sock *sk, struct sk_buff *skb); + + extern int llc_conn_ac_clear_remote_busy(struct sock *sk, struct sk_buff *skb); + extern int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb); +diff --git a/include/net/llc_c_ev.h b/include/net/llc_c_ev.h +index 6ca3113..f8026dd 100644 +--- a/include/net/llc_c_ev.h ++++ b/include/net/llc_c_ev.h +@@ -125,8 +125,8 @@ static __inline__ struct llc_conn_state_ev *llc_conn_ev(struct sk_buff *skb) + return (struct llc_conn_state_ev *)skb->cb; + } + +-typedef int (*llc_conn_ev_t)(struct sock *sk, struct sk_buff *skb); +-typedef int (*llc_conn_ev_qfyr_t)(struct sock *sk, struct sk_buff *skb); ++typedef int (* const llc_conn_ev_t)(struct sock *sk, struct sk_buff *skb); ++typedef int (* const llc_conn_ev_qfyr_t)(struct sock *sk, struct sk_buff *skb); + + extern int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb); + extern int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb); +diff --git a/include/net/llc_c_st.h b/include/net/llc_c_st.h +index 0e79cfb..f46db31 100644 +--- a/include/net/llc_c_st.h ++++ b/include/net/llc_c_st.h +@@ -37,7 +37,7 @@ struct llc_conn_state_trans { + u8 next_state; + llc_conn_ev_qfyr_t *ev_qualifiers; + llc_conn_action_t *ev_actions; +-}; ++} __do_const; + + struct llc_conn_state { + u8 current_state; +diff --git a/include/net/llc_s_ac.h b/include/net/llc_s_ac.h +index 37a3bbd..55a4241 100644 +--- a/include/net/llc_s_ac.h ++++ b/include/net/llc_s_ac.h +@@ -23,7 +23,7 @@ + #define SAP_ACT_TEST_IND 9 + + /* All action functions must look like this */ +-typedef int (*llc_sap_action_t)(struct llc_sap *sap, struct sk_buff *skb); ++typedef int (* const llc_sap_action_t)(struct llc_sap *sap, struct sk_buff *skb); + + extern int llc_sap_action_unitdata_ind(struct llc_sap *sap, + struct sk_buff *skb); +diff --git a/include/net/llc_s_st.h b/include/net/llc_s_st.h +index 567c681..cd73ac0 100644 +--- a/include/net/llc_s_st.h ++++ b/include/net/llc_s_st.h +@@ -20,7 +20,7 @@ struct llc_sap_state_trans { + llc_sap_ev_t ev; + u8 next_state; + llc_sap_action_t *ev_actions; +-}; ++} __do_const; + + struct llc_sap_state { + u8 curr_state; +diff --git a/include/net/mac80211.h b/include/net/mac80211.h +index ee50c5e..1bc3b1a 100644 +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -3996,7 +3996,7 @@ struct rate_control_ops { + void (*add_sta_debugfs)(void *priv, void *priv_sta, + struct dentry *dir); + void (*remove_sta_debugfs)(void *priv, void *priv_sta); +-}; ++} __do_const; + + static inline int rate_supported(struct ieee80211_sta *sta, + enum ieee80211_band band, diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 0dab173..1b76af0 100644 --- a/include/net/neighbour.h @@ -68095,7 +71205,7 @@ index 0dab173..1b76af0 100644 struct pneigh_entry { struct pneigh_entry *next; diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h -index de644bc..666aed3 100644 +index de644bc..351fd4e 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -115,7 +115,7 @@ struct net { @@ -68107,6 +71217,15 @@ index de644bc..666aed3 100644 }; /* +@@ -282,7 +282,7 @@ struct pernet_operations { + void (*exit_batch)(struct list_head *net_exit_list); + int *id; + size_t size; +-}; ++} __do_const; + + /* + * Use these carefully. If you implement a network device and it @@ -330,12 +330,12 @@ static inline void unregister_net_sysctl_table(struct ctl_table_header *header) static inline int rt_genid(struct net *net) @@ -68148,6 +71267,32 @@ index 9690b0f..87aded7 100644 } /** +diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h +index 923cb20..deae816 100644 +--- a/include/net/netns/conntrack.h ++++ b/include/net/netns/conntrack.h +@@ -12,10 +12,10 @@ struct nf_conntrack_ecache; + struct nf_proto_net { + #ifdef CONFIG_SYSCTL + struct ctl_table_header *ctl_table_header; +- struct ctl_table *ctl_table; ++ ctl_table_no_const *ctl_table; + #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT + struct ctl_table_header *ctl_compat_header; +- struct ctl_table *ctl_compat_table; ++ ctl_table_no_const *ctl_compat_table; + #endif + #endif + unsigned int users; +@@ -58,7 +58,7 @@ struct nf_ip_net { + struct nf_icmp_net icmpv6; + #if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT) + struct ctl_table_header *ctl_table_header; +- struct ctl_table *ctl_table; ++ ctl_table_no_const *ctl_table; + #endif + }; + diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index 2ae2b83..dbdc85e 100644 --- a/include/net/netns/ipv4.h @@ -68183,6 +71328,19 @@ index 047c047..b9dad15 100644 #define INET6_PROTO_NOPOLICY 0x1 #define INET6_PROTO_FINAL 0x2 +diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h +index 5a15fab..d799ea7 100644 +--- a/include/net/rtnetlink.h ++++ b/include/net/rtnetlink.h +@@ -81,7 +81,7 @@ struct rtnl_link_ops { + const struct net_device *dev); + unsigned int (*get_num_tx_queues)(void); + unsigned int (*get_num_rx_queues)(void); +-}; ++} __do_const; + + extern int __rtnl_link_register(struct rtnl_link_ops *ops); + extern void __rtnl_link_unregister(struct rtnl_link_ops *ops); diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 7fdf298..197e9f7 100644 --- a/include/net/sctp/sctp.h @@ -68200,19 +71358,32 @@ index 7fdf298..197e9f7 100644 #define SCTP_ENABLE_DEBUG #define SCTP_DISABLE_DEBUG #define SCTP_ASSERT(expr, str, func) +diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h +index 2a82d13..62a31c2 100644 +--- a/include/net/sctp/sm.h ++++ b/include/net/sctp/sm.h +@@ -87,7 +87,7 @@ typedef void (sctp_timer_event_t) (unsigned long); + typedef struct { + sctp_state_fn_t *fn; + const char *name; +-} sctp_sm_table_entry_t; ++} __do_const sctp_sm_table_entry_t; + + /* A naming convention of "sctp_sf_xxx" applies to all the state functions + * currently in use. +@@ -299,7 +299,7 @@ __u32 sctp_generate_tag(const struct sctp_endpoint *); + __u32 sctp_generate_tsn(const struct sctp_endpoint *); + + /* Extern declarations for major data structures. */ +-extern sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES]; ++extern sctp_timer_event_t * const sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES]; + + + /* Get the size of a DATA chunk payload. */ diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h -index fdeb85a..0c554d5 100644 +index fdeb85a..1329d95 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h -@@ -497,7 +497,7 @@ struct sctp_af { - int sockaddr_len; - sa_family_t sa_family; - struct list_head list; --}; -+} __do_const; - - struct sctp_af *sctp_get_af_specific(sa_family_t); - int sctp_register_af(struct sctp_af *); @@ -517,7 +517,7 @@ struct sctp_pf { struct sctp_association *asoc); void (*addr_v4map) (struct sctp_sock *, union sctp_addr *); @@ -68287,9 +71458,27 @@ index aed42c7..43890c6 100644 #define TCP_SKB_CB(__skb) ((struct tcp_skb_cb *)&((__skb)->cb[0])) diff --git a/include/net/xfrm.h b/include/net/xfrm.h -index 63445ed..74ef61d 100644 +index 63445ed..d6fc34f 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h +@@ -304,7 +304,7 @@ struct xfrm_policy_afinfo { + struct net_device *dev, + const struct flowi *fl); + struct dst_entry *(*blackhole_route)(struct net *net, struct dst_entry *orig); +-}; ++} __do_const; + + extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo); + extern int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo); +@@ -340,7 +340,7 @@ struct xfrm_state_afinfo { + struct sk_buff *skb); + int (*transport_finish)(struct sk_buff *skb, + int async); +-}; ++} __do_const; + + extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo); + extern int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo); @@ -423,7 +423,7 @@ struct xfrm_mode { struct module *owner; unsigned int encap; @@ -69244,6 +72433,68 @@ index cee4b5c..9c267d9 100644 /* * Ok, we have completed the initial bootup, and * we're essentially up and running. Get rid of the +diff --git a/ipc/ipc_sysctl.c b/ipc/ipc_sysctl.c +index 130dfec..cc88451 100644 +--- a/ipc/ipc_sysctl.c ++++ b/ipc/ipc_sysctl.c +@@ -30,7 +30,7 @@ static void *get_ipc(ctl_table *table) + static int proc_ipc_dointvec(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { +- struct ctl_table ipc_table; ++ ctl_table_no_const ipc_table; + + memcpy(&ipc_table, table, sizeof(ipc_table)); + ipc_table.data = get_ipc(table); +@@ -41,7 +41,7 @@ static int proc_ipc_dointvec(ctl_table *table, int write, + static int proc_ipc_dointvec_minmax(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { +- struct ctl_table ipc_table; ++ ctl_table_no_const ipc_table; + + memcpy(&ipc_table, table, sizeof(ipc_table)); + ipc_table.data = get_ipc(table); +@@ -65,7 +65,7 @@ static int proc_ipc_dointvec_minmax_orphans(ctl_table *table, int write, + static int proc_ipc_callback_dointvec(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { +- struct ctl_table ipc_table; ++ ctl_table_no_const ipc_table; + size_t lenp_bef = *lenp; + int rc; + +@@ -88,7 +88,7 @@ static int proc_ipc_callback_dointvec(ctl_table *table, int write, + static int proc_ipc_doulongvec_minmax(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { +- struct ctl_table ipc_table; ++ ctl_table_no_const ipc_table; + memcpy(&ipc_table, table, sizeof(ipc_table)); + ipc_table.data = get_ipc(table); + +@@ -122,7 +122,7 @@ static void ipc_auto_callback(int val) + static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { +- struct ctl_table ipc_table; ++ ctl_table_no_const ipc_table; + size_t lenp_bef = *lenp; + int oldval; + int rc; +diff --git a/ipc/mq_sysctl.c b/ipc/mq_sysctl.c +index 383d638..943fdbb 100644 +--- a/ipc/mq_sysctl.c ++++ b/ipc/mq_sysctl.c +@@ -25,7 +25,7 @@ static void *get_mq(ctl_table *table) + static int proc_mq_dointvec_minmax(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { +- struct ctl_table mq_table; ++ ctl_table_no_const mq_table; + memcpy(&mq_table, table, sizeof(mq_table)); + mq_table.data = get_mq(table); + diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 71a3ca1..cc330ee 100644 --- a/ipc/mqueue.c @@ -70767,7 +74018,7 @@ index 5e4bd78..00c5b91 100644 /* Don't allow clients that don't understand the native diff --git a/kernel/kmod.c b/kernel/kmod.c -index 0023a87..b893e79 100644 +index 0023a87..9c0c068 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -74,7 +74,7 @@ static void free_modprobe_argv(struct subprocess_info *info) @@ -70904,6 +74155,15 @@ index 0023a87..b893e79 100644 /* * If ret is 0, either ____call_usermodehelper failed and the +@@ -635,7 +688,7 @@ EXPORT_SYMBOL(call_usermodehelper_fns); + static int proc_cap_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { +- struct ctl_table t; ++ ctl_table_no_const t; + unsigned long cap_array[_KERNEL_CAPABILITY_U32S]; + kernel_cap_t new_cap; + int err, i; diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 098f396..fe85ff1 100644 --- a/kernel/kprobes.c @@ -70959,7 +74219,7 @@ index 098f396..fe85ff1 100644 head = &kprobe_table[i]; preempt_disable(); diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c -index 6ada93c..55baf4d 100644 +index 6ada93c..dce7d5d 100644 --- a/kernel/ksysfs.c +++ b/kernel/ksysfs.c @@ -46,6 +46,8 @@ static ssize_t uevent_helper_store(struct kobject *kobj, @@ -70971,6 +74231,15 @@ index 6ada93c..55baf4d 100644 memcpy(uevent_helper, buf, count); uevent_helper[count] = '\0'; if (count && uevent_helper[count-1] == '\n') +@@ -172,7 +174,7 @@ static ssize_t notes_read(struct file *filp, struct kobject *kobj, + return count; + } + +-static struct bin_attribute notes_attr = { ++static bin_attribute_no_const notes_attr __read_only = { + .attr = { + .name = "notes", + .mode = S_IRUGO, diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 7981e5b..7f2105c 100644 --- a/kernel/lockdep.c @@ -71053,7 +74322,7 @@ index b2c71c5..7b88d63 100644 seq_printf(m, "%40s %14lu %29s %pS\n", name, stats->contending_point[i], diff --git a/kernel/module.c b/kernel/module.c -index eab0827..75ede66 100644 +index eab0827..f488603 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -61,6 +61,7 @@ @@ -71128,6 +74397,24 @@ index eab0827..75ede66 100644 static inline bool sect_empty(const Elf_Shdr *sect) { return !(sect->sh_flags & SHF_ALLOC) || sect->sh_size == 0; +@@ -1451,7 +1453,7 @@ static void add_notes_attrs(struct module *mod, const struct load_info *info) + { + unsigned int notes, loaded, i; + struct module_notes_attrs *notes_attrs; +- struct bin_attribute *nattr; ++ bin_attribute_no_const *nattr; + + /* failed to create section attributes, so can't create notes */ + if (!mod->sect_attrs) +@@ -1563,7 +1565,7 @@ static void del_usage_links(struct module *mod) + static int module_add_modinfo_attrs(struct module *mod) + { + struct module_attribute *attr; +- struct module_attribute *temp_attr; ++ module_attribute_no_const *temp_attr; + int error = 0; + int i; + @@ -1777,21 +1779,21 @@ static void set_section_ro_nx(void *base, static void unset_module_core_ro_nx(struct module *mod) @@ -72050,6 +75337,19 @@ index f2c6a68..4922d97 100644 struct pid *get_task_pid(struct task_struct *task, enum pid_type type) { struct pid *pid; +diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c +index c1c3dc1..bbeaf31 100644 +--- a/kernel/pid_namespace.c ++++ b/kernel/pid_namespace.c +@@ -248,7 +248,7 @@ static int pid_ns_ctl_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + struct pid_namespace *pid_ns = task_active_pid_ns(current); +- struct ctl_table tmp = *table; ++ ctl_table_no_const tmp = *table; + + if (write && !ns_capable(pid_ns->user_ns, CAP_SYS_ADMIN)) + return -EPERM; diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 942ca27..111e609 100644 --- a/kernel/posix-cpu-timers.c @@ -72915,7 +76215,7 @@ index 4b69291..704c92e 100644 unsigned long jiffies_force_qs; /* Time at which to invoke */ /* force_quiescent_state(). */ diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h -index c1cc7e1..5043e0e 100644 +index c1cc7e1..f62e436 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h @@ -892,7 +892,7 @@ void synchronize_rcu_expedited(void) @@ -72927,6 +76227,15 @@ index c1cc7e1..5043e0e 100644 unlock_mb_ret: mutex_unlock(&sync_rcu_preempt_exp_mutex); mb_ret: +@@ -1440,7 +1440,7 @@ static void rcu_boost_kthread_setaffinity(struct rcu_node *rnp, int outgoingcpu) + free_cpumask_var(cm); + } + +-static struct smp_hotplug_thread rcu_cpu_thread_spec = { ++static struct smp_hotplug_thread rcu_cpu_thread_spec __read_only = { + .store = &rcu_cpu_kthread_task, + .thread_should_run = rcu_cpu_kthread_should_run, + .thread_fn = rcu_cpu_kthread, @@ -2072,7 +2072,7 @@ static void print_cpu_stall_info(struct rcu_state *rsp, int cpu) print_cpu_stall_fast_no_hz(fast_no_hz, cpu); printk(KERN_ERR "\t%d: (%lu %s) idle=%03x/%llx/%d %s\n", @@ -73162,7 +76471,7 @@ index 0984a21..939f183 100644 #ifdef CONFIG_RT_GROUP_SCHED /* diff --git a/kernel/sched/core.c b/kernel/sched/core.c -index 26058d0..06f15dd 100644 +index 26058d0..f9d3c76 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -3631,6 +3631,8 @@ int can_nice(const struct task_struct *p, const int nice) @@ -73192,7 +76501,121 @@ index 26058d0..06f15dd 100644 /* can't set/change the rt policy */ if (policy != p->policy && !rlim_rtprio) return -EPERM; -@@ -5162,7 +5166,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) +@@ -4901,7 +4905,7 @@ static void migrate_tasks(unsigned int dead_cpu) + + #if defined(CONFIG_SCHED_DEBUG) && defined(CONFIG_SYSCTL) + +-static struct ctl_table sd_ctl_dir[] = { ++static ctl_table_no_const sd_ctl_dir[] __read_only = { + { + .procname = "sched_domain", + .mode = 0555, +@@ -4918,17 +4922,17 @@ static struct ctl_table sd_ctl_root[] = { + {} + }; + +-static struct ctl_table *sd_alloc_ctl_entry(int n) ++static ctl_table_no_const *sd_alloc_ctl_entry(int n) + { +- struct ctl_table *entry = ++ ctl_table_no_const *entry = + kcalloc(n, sizeof(struct ctl_table), GFP_KERNEL); + + return entry; + } + +-static void sd_free_ctl_entry(struct ctl_table **tablep) ++static void sd_free_ctl_entry(ctl_table_no_const *tablep) + { +- struct ctl_table *entry; ++ ctl_table_no_const *entry; + + /* + * In the intermediate directories, both the child directory and +@@ -4936,22 +4940,25 @@ static void sd_free_ctl_entry(struct ctl_table **tablep) + * will always be set. In the lowest directory the names are + * static strings and all have proc handlers. + */ +- for (entry = *tablep; entry->mode; entry++) { +- if (entry->child) +- sd_free_ctl_entry(&entry->child); ++ for (entry = tablep; entry->mode; entry++) { ++ if (entry->child) { ++ sd_free_ctl_entry(entry->child); ++ pax_open_kernel(); ++ entry->child = NULL; ++ pax_close_kernel(); ++ } + if (entry->proc_handler == NULL) + kfree(entry->procname); + } + +- kfree(*tablep); +- *tablep = NULL; ++ kfree(tablep); + } + + static int min_load_idx = 0; + static int max_load_idx = CPU_LOAD_IDX_MAX; + + static void +-set_table_entry(struct ctl_table *entry, ++set_table_entry(ctl_table_no_const *entry, + const char *procname, void *data, int maxlen, + umode_t mode, proc_handler *proc_handler, + bool load_idx) +@@ -4971,7 +4978,7 @@ set_table_entry(struct ctl_table *entry, + static struct ctl_table * + sd_alloc_ctl_domain_table(struct sched_domain *sd) + { +- struct ctl_table *table = sd_alloc_ctl_entry(13); ++ ctl_table_no_const *table = sd_alloc_ctl_entry(13); + + if (table == NULL) + return NULL; +@@ -5006,9 +5013,9 @@ sd_alloc_ctl_domain_table(struct sched_domain *sd) + return table; + } + +-static ctl_table *sd_alloc_ctl_cpu_table(int cpu) ++static ctl_table_no_const *sd_alloc_ctl_cpu_table(int cpu) + { +- struct ctl_table *entry, *table; ++ ctl_table_no_const *entry, *table; + struct sched_domain *sd; + int domain_num = 0, i; + char buf[32]; +@@ -5035,11 +5042,13 @@ static struct ctl_table_header *sd_sysctl_header; + static void register_sched_domain_sysctl(void) + { + int i, cpu_num = num_possible_cpus(); +- struct ctl_table *entry = sd_alloc_ctl_entry(cpu_num + 1); ++ ctl_table_no_const *entry = sd_alloc_ctl_entry(cpu_num + 1); + char buf[32]; + + WARN_ON(sd_ctl_dir[0].child); ++ pax_open_kernel(); + sd_ctl_dir[0].child = entry; ++ pax_close_kernel(); + + if (entry == NULL) + return; +@@ -5062,8 +5071,12 @@ static void unregister_sched_domain_sysctl(void) + if (sd_sysctl_header) + unregister_sysctl_table(sd_sysctl_header); + sd_sysctl_header = NULL; +- if (sd_ctl_dir[0].child) +- sd_free_ctl_entry(&sd_ctl_dir[0].child); ++ if (sd_ctl_dir[0].child) { ++ sd_free_ctl_entry(sd_ctl_dir[0].child); ++ pax_open_kernel(); ++ sd_ctl_dir[0].child = NULL; ++ pax_close_kernel(); ++ } + } + #else + static void register_sched_domain_sysctl(void) +@@ -5162,7 +5175,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) * happens before everything else. This has to be lower priority than * the notifier in the perf_event subsystem, though. */ @@ -73415,8 +76838,30 @@ index 69f38bd..77bbf12 100644 .notifier_call = hotplug_cfd, }; +diff --git a/kernel/smpboot.c b/kernel/smpboot.c +index d6c5fc0..530560c 100644 +--- a/kernel/smpboot.c ++++ b/kernel/smpboot.c +@@ -275,7 +275,7 @@ int smpboot_register_percpu_thread(struct smp_hotplug_thread *plug_thread) + } + smpboot_unpark_thread(plug_thread, cpu); + } +- list_add(&plug_thread->list, &hotplug_threads); ++ pax_list_add(&plug_thread->list, &hotplug_threads); + out: + mutex_unlock(&smpboot_threads_lock); + return ret; +@@ -292,7 +292,7 @@ void smpboot_unregister_percpu_thread(struct smp_hotplug_thread *plug_thread) + { + get_online_cpus(); + mutex_lock(&smpboot_threads_lock); +- list_del(&plug_thread->list); ++ pax_list_del(&plug_thread->list); + smpboot_destroy_threads(plug_thread); + mutex_unlock(&smpboot_threads_lock); + put_online_cpus(); diff --git a/kernel/softirq.c b/kernel/softirq.c -index ed567ba..dc61b61 100644 +index ed567ba..e71dabf 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -53,11 +53,11 @@ irq_cpustat_t irq_stat[NR_CPUS] ____cacheline_aligned; @@ -73478,7 +76923,7 @@ index ed567ba..dc61b61 100644 .notifier_call = remote_softirq_cpu_notify, }; -@@ -835,7 +835,7 @@ static int __cpuinit cpu_callback(struct notifier_block *nfb, +@@ -835,11 +835,11 @@ static int __cpuinit cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } @@ -73487,6 +76932,11 @@ index ed567ba..dc61b61 100644 .notifier_call = cpu_callback }; +-static struct smp_hotplug_thread softirq_threads = { ++static struct smp_hotplug_thread softirq_threads __read_only = { + .store = &ksoftirqd, + .thread_should_run = ksoftirqd_should_run, + .thread_fn = run_ksoftirqd, diff --git a/kernel/srcu.c b/kernel/srcu.c index 2b85982..d52ab26 100644 --- a/kernel/srcu.c @@ -73685,7 +77135,7 @@ index 265b376..4e42ef5 100644 break; } diff --git a/kernel/sysctl.c b/kernel/sysctl.c -index c88878d..99d321b 100644 +index c88878d..e4fa5d1 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -92,7 +92,6 @@ @@ -73831,6 +77281,15 @@ index c88878d..99d321b 100644 if (copy_to_user(*buf, tmp, len)) return -EFAULT; *size -= len; +@@ -1985,7 +2037,7 @@ int proc_dointvec(struct ctl_table *table, int write, + static int proc_taint(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { +- struct ctl_table t; ++ ctl_table_no_const t; + unsigned long tmptaint = get_taint(); + int err; + @@ -2013,7 +2065,6 @@ static int proc_taint(struct ctl_table *table, int write, return err; } @@ -74775,10 +78234,63 @@ index 2b042c4..24f8ec3 100644 } EXPORT_SYMBOL(free_user_ns); +diff --git a/kernel/utsname_sysctl.c b/kernel/utsname_sysctl.c +index 63da38c..639904e 100644 +--- a/kernel/utsname_sysctl.c ++++ b/kernel/utsname_sysctl.c +@@ -46,7 +46,7 @@ static void put_uts(ctl_table *table, int write, void *which) + static int proc_do_uts_string(ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { +- struct ctl_table uts_table; ++ ctl_table_no_const uts_table; + int r; + memcpy(&uts_table, table, sizeof(uts_table)); + uts_table.data = get_uts(table, write); +diff --git a/kernel/watchdog.c b/kernel/watchdog.c +index 75a2ab3..5961da7 100644 +--- a/kernel/watchdog.c ++++ b/kernel/watchdog.c +@@ -527,7 +527,7 @@ int proc_dowatchdog(struct ctl_table *table, int write, + } + #endif /* CONFIG_SYSCTL */ + +-static struct smp_hotplug_thread watchdog_threads = { ++static struct smp_hotplug_thread watchdog_threads __read_only = { + .store = &softlockup_watchdog, + .thread_should_run = watchdog_should_run, + .thread_fn = watchdog, diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug -index 67604e5..3ebb003 100644 +index 67604e5..fe94fb1 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug +@@ -550,7 +550,7 @@ config DEBUG_MUTEXES + + config DEBUG_LOCK_ALLOC + bool "Lock debugging: detect incorrect freeing of live locks" +- depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT ++ depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT && !PAX_CONSTIFY_PLUGIN + select DEBUG_SPINLOCK + select DEBUG_MUTEXES + select LOCKDEP +@@ -564,7 +564,7 @@ config DEBUG_LOCK_ALLOC + + config PROVE_LOCKING + bool "Lock debugging: prove locking correctness" +- depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT ++ depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT && !PAX_CONSTIFY_PLUGIN + select LOCKDEP + select DEBUG_SPINLOCK + select DEBUG_MUTEXES +@@ -670,7 +670,7 @@ config LOCKDEP + + config LOCK_STAT + bool "Lock usage statistics" +- depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT ++ depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT && !PAX_CONSTIFY_PLUGIN + select LOCKDEP + select DEBUG_SPINLOCK + select DEBUG_MUTEXES @@ -1278,6 +1278,7 @@ config LATENCYTOP depends on DEBUG_KERNEL depends on STACKTRACE_SUPPORT @@ -74977,8 +78489,24 @@ index bd2bea9..6b3c95e 100644 if (atomic_read(&task->signal->live) != 1) return false; +diff --git a/lib/kobject.c b/lib/kobject.c +index e07ee1f..998489d 100644 +--- a/lib/kobject.c ++++ b/lib/kobject.c +@@ -852,9 +852,9 @@ EXPORT_SYMBOL_GPL(kset_create_and_add); + + + static DEFINE_SPINLOCK(kobj_ns_type_lock); +-static const struct kobj_ns_type_operations *kobj_ns_ops_tbl[KOBJ_NS_TYPES]; ++static const struct kobj_ns_type_operations *kobj_ns_ops_tbl[KOBJ_NS_TYPES] __read_only; + +-int kobj_ns_type_register(const struct kobj_ns_type_operations *ops) ++int __init kobj_ns_type_register(const struct kobj_ns_type_operations *ops) + { + enum kobj_ns_type type = ops->type; + int error; diff --git a/lib/list_debug.c b/lib/list_debug.c -index c24c2f7..3fc5da0 100644 +index c24c2f7..0475b78 100644 --- a/lib/list_debug.c +++ b/lib/list_debug.c @@ -11,7 +11,9 @@ @@ -75060,20 +78588,17 @@ index c24c2f7..3fc5da0 100644 } EXPORT_SYMBOL(__list_del_entry); -@@ -86,15 +106,54 @@ EXPORT_SYMBOL(list_del); +@@ -86,15 +106,85 @@ EXPORT_SYMBOL(list_del); void __list_add_rcu(struct list_head *new, struct list_head *prev, struct list_head *next) { - WARN(next->prev != prev, -+ if (WARN(next->prev != prev, - "list_add_rcu corruption. next->prev should be prev (%p), but was %p. (next=%p).\n", +- "list_add_rcu corruption. next->prev should be prev (%p), but was %p. (next=%p).\n", - prev, next->prev, next); - WARN(prev->next != next, -+ prev, next->prev, next) || -+ WARN(prev->next != next, - "list_add_rcu corruption. prev->next should be next (%p), but was %p. (prev=%p).\n", +- "list_add_rcu corruption. prev->next should be next (%p), but was %p. (prev=%p).\n", - next, prev->next, prev); -+ next, prev->next, prev)) ++ if (!__list_add_debug(new, prev, next)) + return; + new->next = next; @@ -75084,13 +78609,8 @@ index c24c2f7..3fc5da0 100644 EXPORT_SYMBOL(__list_add_rcu); +#endif + -+void pax_list_add_tail(struct list_head *new, struct list_head *head) ++void __pax_list_add(struct list_head *new, struct list_head *prev, struct list_head *next) +{ -+ struct list_head *prev, *next; -+ -+ prev = head->prev; -+ next = head; -+ +#ifdef CONFIG_DEBUG_LIST + if (!__list_add_debug(new, prev, next)) + return; @@ -75103,7 +78623,7 @@ index c24c2f7..3fc5da0 100644 + prev->next = new; + pax_close_kernel(); +} -+EXPORT_SYMBOL(pax_list_add_tail); ++EXPORT_SYMBOL(__pax_list_add); + +void pax_list_del(struct list_head *entry) +{ @@ -75119,6 +78639,47 @@ index c24c2f7..3fc5da0 100644 + pax_close_kernel(); +} +EXPORT_SYMBOL(pax_list_del); ++ ++void pax_list_del_init(struct list_head *entry) ++{ ++ pax_open_kernel(); ++ __list_del(entry->prev, entry->next); ++ INIT_LIST_HEAD(entry); ++ pax_close_kernel(); ++} ++EXPORT_SYMBOL(pax_list_del_init); ++ ++void __pax_list_add_rcu(struct list_head *new, ++ struct list_head *prev, struct list_head *next) ++{ ++#ifdef CONFIG_DEBUG_LIST ++ if (!__list_add_debug(new, prev, next)) ++ return; ++#endif ++ ++ pax_open_kernel(); ++ new->next = next; ++ new->prev = prev; ++ rcu_assign_pointer(list_next_rcu(prev), new); ++ next->prev = new; ++ pax_close_kernel(); ++} ++EXPORT_SYMBOL(__pax_list_add_rcu); ++ ++void pax_list_del_rcu(struct list_head *entry) ++{ ++#ifdef CONFIG_DEBUG_LIST ++ if (!__list_del_entry_debug(entry)) ++ return; ++#endif ++ ++ pax_open_kernel(); ++ __list_del(entry->prev, entry->next); ++ entry->next = LIST_POISON1; ++ entry->prev = LIST_POISON2; ++ pax_close_kernel(); ++} ++EXPORT_SYMBOL(pax_list_del_rcu); diff --git a/lib/radix-tree.c b/lib/radix-tree.c index e796429..6e38f9f 100644 --- a/lib/radix-tree.c @@ -75158,6 +78719,19 @@ index a28df52..3d55877 100644 long align, res = 0; unsigned long c; +diff --git a/lib/swiotlb.c b/lib/swiotlb.c +index 196b069..358f342 100644 +--- a/lib/swiotlb.c ++++ b/lib/swiotlb.c +@@ -642,7 +642,7 @@ EXPORT_SYMBOL(swiotlb_alloc_coherent); + + void + swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, +- dma_addr_t dev_addr) ++ dma_addr_t dev_addr, struct dma_attrs *attrs) + { + phys_addr_t paddr = dma_to_phys(hwdev, dev_addr); + diff --git a/lib/vsprintf.c b/lib/vsprintf.c index fab33a9..3b5fe68 100644 --- a/lib/vsprintf.c @@ -75386,10 +78960,52 @@ index b32b70c..e512eb0 100644 set_page_address(page, (void *)vaddr); diff --git a/mm/hugetlb.c b/mm/hugetlb.c -index 546db81..01d5c53 100644 +index 546db81..34830af 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c -@@ -2511,6 +2511,27 @@ static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2008,15 +2008,17 @@ static int hugetlb_sysctl_handler_common(bool obey_mempolicy, + struct hstate *h = &default_hstate; + unsigned long tmp; + int ret; ++ ctl_table_no_const hugetlb_table; + + tmp = h->max_huge_pages; + + if (write && h->order >= MAX_ORDER) + return -EINVAL; + +- table->data = &tmp; +- table->maxlen = sizeof(unsigned long); +- ret = proc_doulongvec_minmax(table, write, buffer, length, ppos); ++ hugetlb_table = *table; ++ hugetlb_table.data = &tmp; ++ hugetlb_table.maxlen = sizeof(unsigned long); ++ ret = proc_doulongvec_minmax(&hugetlb_table, write, buffer, length, ppos); + if (ret) + goto out; + +@@ -2073,15 +2075,17 @@ int hugetlb_overcommit_handler(struct ctl_table *table, int write, + struct hstate *h = &default_hstate; + unsigned long tmp; + int ret; ++ ctl_table_no_const hugetlb_table; + + tmp = h->nr_overcommit_huge_pages; + + if (write && h->order >= MAX_ORDER) + return -EINVAL; + +- table->data = &tmp; +- table->maxlen = sizeof(unsigned long); +- ret = proc_doulongvec_minmax(table, write, buffer, length, ppos); ++ hugetlb_table = *table; ++ hugetlb_table.data = &tmp; ++ hugetlb_table.maxlen = sizeof(unsigned long); ++ ret = proc_doulongvec_minmax(&hugetlb_table, write, buffer, length, ppos); + if (ret) + goto out; + +@@ -2511,6 +2515,27 @@ static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma, return 1; } @@ -75417,7 +79033,7 @@ index 546db81..01d5c53 100644 /* * Hugetlb_cow() should be called with page lock of the original hugepage held. * Called with hugetlb_instantiation_mutex held and pte_page locked so we -@@ -2629,6 +2650,11 @@ retry_avoidcopy: +@@ -2629,6 +2654,11 @@ retry_avoidcopy: make_huge_pte(vma, new_page, 1)); page_remove_rmap(old_page); hugepage_add_new_anon_rmap(new_page, vma, address); @@ -75429,7 +79045,7 @@ index 546db81..01d5c53 100644 /* Make the old page be freed below */ new_page = old_page; } -@@ -2788,6 +2814,10 @@ retry: +@@ -2788,6 +2818,10 @@ retry: && (vma->vm_flags & VM_SHARED))); set_huge_pte_at(mm, address, ptep, new_pte); @@ -75440,7 +79056,7 @@ index 546db81..01d5c53 100644 if ((flags & FAULT_FLAG_WRITE) && !(vma->vm_flags & VM_SHARED)) { /* Optimization, do the COW without a second fault */ ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page); -@@ -2817,6 +2847,10 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2817,6 +2851,10 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, static DEFINE_MUTEX(hugetlb_instantiation_mutex); struct hstate *h = hstate_vma(vma); @@ -75451,7 +79067,7 @@ index 546db81..01d5c53 100644 address &= huge_page_mask(h); ptep = huge_pte_offset(mm, address); -@@ -2830,6 +2864,26 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2830,6 +2868,26 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, VM_FAULT_SET_HINDEX(hstate_index(h)); } @@ -75615,7 +79231,7 @@ index 03dfa5c..b032917 100644 if (end == start) goto out; diff --git a/mm/memory-failure.c b/mm/memory-failure.c -index c6e4dd3..fdb2ca6 100644 +index c6e4dd3..1f41988 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -61,7 +61,7 @@ int sysctl_memory_failure_early_kill __read_mostly = 0; @@ -75636,6 +79252,15 @@ index c6e4dd3..fdb2ca6 100644 #ifdef __ARCH_SI_TRAPNO si.si_trapno = trapno; #endif +@@ -760,7 +760,7 @@ static struct page_state { + unsigned long res; + char *msg; + int (*action)(struct page *p, unsigned long pfn); +-} error_states[] = { ++} __do_const error_states[] = { + { reserved, reserved, "reserved kernel", me_kernel }, + /* + * free pages are specially detected outside this table: @@ -1040,7 +1040,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags) } @@ -78591,9 +82216,18 @@ index 34a98d6..73633d1 100644 if (slab_equal_or_root(cachep, s)) return cachep; diff --git a/mm/slab_common.c b/mm/slab_common.c -index 3f3cd97..e050794 100644 +index 3f3cd97..93b0236 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c +@@ -22,7 +22,7 @@ + + #include "slab.h" + +-enum slab_state slab_state; ++enum slab_state slab_state __read_only; + LIST_HEAD(slab_caches); + DEFINE_MUTEX(slab_mutex); + struct kmem_cache *kmem_cache; @@ -209,7 +209,7 @@ kmem_cache_create_memcg(struct mem_cgroup *memcg, const char *name, size_t size, err = __kmem_cache_create(s, flags); @@ -79674,6 +83308,28 @@ index a292e80..785ee68 100644 struct vlan_net *vn; vn = net_generic(net, vlan_net_id); +diff --git a/net/9p/mod.c b/net/9p/mod.c +index 6ab36ae..6f1841b 100644 +--- a/net/9p/mod.c ++++ b/net/9p/mod.c +@@ -84,7 +84,7 @@ static LIST_HEAD(v9fs_trans_list); + void v9fs_register_trans(struct p9_trans_module *m) + { + spin_lock(&v9fs_trans_lock); +- list_add_tail(&m->list, &v9fs_trans_list); ++ pax_list_add_tail((struct list_head *)&m->list, &v9fs_trans_list); + spin_unlock(&v9fs_trans_lock); + } + EXPORT_SYMBOL(v9fs_register_trans); +@@ -97,7 +97,7 @@ EXPORT_SYMBOL(v9fs_register_trans); + void v9fs_unregister_trans(struct p9_trans_module *m) + { + spin_lock(&v9fs_trans_lock); +- list_del_init(&m->list); ++ pax_list_del_init((struct list_head *)&m->list); + spin_unlock(&v9fs_trans_lock); + } + EXPORT_SYMBOL(v9fs_unregister_trans); diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 02efb25..41541a9 100644 --- a/net/9p/trans_fd.c @@ -79779,6 +83435,19 @@ index 0447d5d..3cf4728 100644 __AAL_STAT_ITEMS #undef __HANDLE_ITEM } +diff --git a/net/ax25/sysctl_net_ax25.c b/net/ax25/sysctl_net_ax25.c +index d5744b7..506bae3 100644 +--- a/net/ax25/sysctl_net_ax25.c ++++ b/net/ax25/sysctl_net_ax25.c +@@ -152,7 +152,7 @@ int ax25_register_dev_sysctl(ax25_dev *ax25_dev) + { + char path[sizeof("net/ax25/") + IFNAMSIZ]; + int k; +- struct ctl_table *table; ++ ctl_table_no_const *table; + + table = kmemdup(ax25_param_table, sizeof(ax25_param_table), GFP_KERNEL); + if (!table) diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 7d02ebd..4d4cc01 100644 --- a/net/batman-adv/bat_iv_ogm.c @@ -80480,8 +84149,74 @@ index 7e7aeb0..2a998cb 100644 return -EFAULT; m->msg_iov = iov; +diff --git a/net/core/neighbour.c b/net/core/neighbour.c +index c815f28..e6403f2 100644 +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -2776,7 +2776,7 @@ static int proc_unres_qlen(ctl_table *ctl, int write, void __user *buffer, + size_t *lenp, loff_t *ppos) + { + int size, ret; +- ctl_table tmp = *ctl; ++ ctl_table_no_const tmp = *ctl; + + tmp.extra1 = &zero; + tmp.extra2 = &unres_qlen_max; +diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c +index 28c5f5a..7edf2e2 100644 +--- a/net/core/net-sysfs.c ++++ b/net/core/net-sysfs.c +@@ -1455,7 +1455,7 @@ void netdev_class_remove_file(struct class_attribute *class_attr) + } + EXPORT_SYMBOL(netdev_class_remove_file); + +-int netdev_kobject_init(void) ++int __init netdev_kobject_init(void) + { + kobj_ns_type_register(&net_ns_type_operations); + return class_register(&net_class); +diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c +index 8acce01..2e306bb 100644 +--- a/net/core/net_namespace.c ++++ b/net/core/net_namespace.c +@@ -442,7 +442,7 @@ static int __register_pernet_operations(struct list_head *list, + int error; + LIST_HEAD(net_exit_list); + +- list_add_tail(&ops->list, list); ++ pax_list_add_tail((struct list_head *)&ops->list, list); + if (ops->init || (ops->id && ops->size)) { + for_each_net(net) { + error = ops_init(ops, net); +@@ -455,7 +455,7 @@ static int __register_pernet_operations(struct list_head *list, + + out_undo: + /* If I have an error cleanup all namespaces I initialized */ +- list_del(&ops->list); ++ pax_list_del((struct list_head *)&ops->list); + ops_exit_list(ops, &net_exit_list); + ops_free_list(ops, &net_exit_list); + return error; +@@ -466,7 +466,7 @@ static void __unregister_pernet_operations(struct pernet_operations *ops) + struct net *net; + LIST_HEAD(net_exit_list); + +- list_del(&ops->list); ++ pax_list_del((struct list_head *)&ops->list); + for_each_net(net) + list_add_tail(&net->exit_list, &net_exit_list); + ops_exit_list(ops, &net_exit_list); +@@ -600,7 +600,7 @@ int register_pernet_device(struct pernet_operations *ops) + mutex_lock(&net_mutex); + error = register_pernet_operations(&pernet_list, ops); + if (!error && (first_device == &pernet_list)) +- first_device = &ops->list; ++ first_device = (struct list_head *)&ops->list; + mutex_unlock(&net_mutex); + return error; + } diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index 1868625..5f4de62 100644 +index 1868625..b1b1284 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -58,7 +58,7 @@ struct rtnl_link { @@ -80493,6 +84228,32 @@ index 1868625..5f4de62 100644 static DEFINE_MUTEX(rtnl_mutex); +@@ -299,10 +299,13 @@ int __rtnl_link_register(struct rtnl_link_ops *ops) + if (rtnl_link_ops_get(ops->kind)) + return -EEXIST; + +- if (!ops->dellink) +- ops->dellink = unregister_netdevice_queue; ++ if (!ops->dellink) { ++ pax_open_kernel(); ++ *(void **)&ops->dellink = unregister_netdevice_queue; ++ pax_close_kernel(); ++ } + +- list_add_tail(&ops->list, &link_ops); ++ pax_list_add_tail((struct list_head *)&ops->list, &link_ops); + return 0; + } + EXPORT_SYMBOL_GPL(__rtnl_link_register); +@@ -349,7 +352,7 @@ void __rtnl_link_unregister(struct rtnl_link_ops *ops) + for_each_net(net) { + __rtnl_kill_links(net, ops); + } +- list_del(&ops->list); ++ pax_list_del((struct list_head *)&ops->list); + } + EXPORT_SYMBOL_GPL(__rtnl_link_unregister); + diff --git a/net/core/scm.c b/net/core/scm.c index 905dcc6..14ee2d6 100644 --- a/net/core/scm.c @@ -80631,10 +84392,17 @@ index bc131d4..029e378 100644 EXPORT_SYMBOL(sock_init_data); diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c -index 750f44f..0a699b1 100644 +index 750f44f..922399c 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c -@@ -15,20 +15,27 @@ static DEFINE_MUTEX(sock_diag_table_mutex); +@@ -9,26 +9,33 @@ + #include <linux/inet_diag.h> + #include <linux/sock_diag.h> + +-static const struct sock_diag_handler *sock_diag_handlers[AF_MAX]; ++static const struct sock_diag_handler *sock_diag_handlers[AF_MAX] __read_only; + static int (*inet_rcv_compat)(struct sk_buff *skb, struct nlmsghdr *nlh); + static DEFINE_MUTEX(sock_diag_table_mutex); int sock_diag_check_cookie(void *sk, __u32 *cookie) { @@ -80662,7 +84430,27 @@ index 750f44f..0a699b1 100644 } EXPORT_SYMBOL_GPL(sock_diag_save_cookie); -@@ -97,21 +104,6 @@ void sock_diag_unregister(const struct sock_diag_handler *hnld) +@@ -75,8 +82,11 @@ int sock_diag_register(const struct sock_diag_handler *hndl) + mutex_lock(&sock_diag_table_mutex); + if (sock_diag_handlers[hndl->family]) + err = -EBUSY; +- else ++ else { ++ pax_open_kernel(); + sock_diag_handlers[hndl->family] = hndl; ++ pax_close_kernel(); ++ } + mutex_unlock(&sock_diag_table_mutex); + + return err; +@@ -92,26 +102,13 @@ void sock_diag_unregister(const struct sock_diag_handler *hnld) + + mutex_lock(&sock_diag_table_mutex); + BUG_ON(sock_diag_handlers[family] != hnld); ++ pax_open_kernel(); + sock_diag_handlers[family] = NULL; ++ pax_close_kernel(); + mutex_unlock(&sock_diag_table_mutex); } EXPORT_SYMBOL_GPL(sock_diag_unregister); @@ -80684,7 +84472,7 @@ index 750f44f..0a699b1 100644 static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) { int err; -@@ -124,12 +116,17 @@ static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) +@@ -124,12 +121,17 @@ static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (req->sdiag_family >= AF_MAX) return -EINVAL; @@ -80704,6 +84492,77 @@ index 750f44f..0a699b1 100644 return err; } +diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c +index d1b0804..4aed0a5 100644 +--- a/net/core/sysctl_net_core.c ++++ b/net/core/sysctl_net_core.c +@@ -26,7 +26,7 @@ static int rps_sock_flow_sysctl(ctl_table *table, int write, + { + unsigned int orig_size, size; + int ret, i; +- ctl_table tmp = { ++ ctl_table_no_const tmp = { + .data = &size, + .maxlen = sizeof(size), + .mode = table->mode +@@ -205,13 +205,12 @@ static struct ctl_table netns_core_table[] = { + + static __net_init int sysctl_core_net_init(struct net *net) + { +- struct ctl_table *tbl; ++ ctl_table_no_const *tbl = NULL; + + net->core.sysctl_somaxconn = SOMAXCONN; + +- tbl = netns_core_table; + if (!net_eq(net, &init_net)) { +- tbl = kmemdup(tbl, sizeof(netns_core_table), GFP_KERNEL); ++ tbl = kmemdup(netns_core_table, sizeof(netns_core_table), GFP_KERNEL); + if (tbl == NULL) + goto err_dup; + +@@ -221,16 +220,16 @@ static __net_init int sysctl_core_net_init(struct net *net) + if (net->user_ns != &init_user_ns) { + tbl[0].procname = NULL; + } +- } +- +- net->core.sysctl_hdr = register_net_sysctl(net, "net/core", tbl); ++ net->core.sysctl_hdr = register_net_sysctl(net, "net/core", tbl); ++ } else ++ net->core.sysctl_hdr = register_net_sysctl(net, "net/core", netns_core_table); + if (net->core.sysctl_hdr == NULL) + goto err_reg; + + return 0; + + err_reg: +- if (tbl != netns_core_table) ++ if (tbl) + kfree(tbl); + err_dup: + return -ENOMEM; +@@ -246,7 +245,7 @@ static __net_exit void sysctl_core_net_exit(struct net *net) + kfree(tbl); + } + +-static __net_initdata struct pernet_operations sysctl_core_ops = { ++static __net_initconst struct pernet_operations sysctl_core_ops = { + .init = sysctl_core_net_init, + .exit = sysctl_core_net_exit, + }; +diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c +index 307c322..78a4c6f 100644 +--- a/net/decnet/af_decnet.c ++++ b/net/decnet/af_decnet.c +@@ -468,6 +468,7 @@ static struct proto dn_proto = { + .sysctl_rmem = sysctl_decnet_rmem, + .max_header = DN_MAX_NSP_DATA_HEADER + 64, + .obj_size = sizeof(struct dn_sock), ++ .slab_flags = SLAB_USERCOPY, + }; + + static struct sock *dn_alloc_sock(struct net *net, struct socket *sock, gfp_t gfp) diff --git a/net/decnet/sysctl_net_decnet.c b/net/decnet/sysctl_net_decnet.c index a55eecc..dd8428c 100644 --- a/net/decnet/sysctl_net_decnet.c @@ -80726,6 +84585,34 @@ index a55eecc..dd8428c 100644 return -EFAULT; *lenp = len; +diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c +index fcf104e..95552d4 100644 +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -1717,13 +1717,9 @@ static int __init inet_init(void) + + BUILD_BUG_ON(sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb)); + +- sysctl_local_reserved_ports = kzalloc(65536 / 8, GFP_KERNEL); +- if (!sysctl_local_reserved_ports) +- goto out; +- + rc = proto_register(&tcp_prot, 1); + if (rc) +- goto out_free_reserved_ports; ++ goto out; + + rc = proto_register(&udp_prot, 1); + if (rc) +@@ -1832,8 +1828,6 @@ out_unregister_udp_proto: + proto_unregister(&udp_prot); + out_unregister_tcp_proto: + proto_unregister(&tcp_prot); +-out_free_reserved_ports: +- kfree(sysctl_local_reserved_ports); + goto out; + } + diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index a69b4e4..dbccba5 100644 --- a/net/ipv4/ah4.c @@ -80739,6 +84626,59 @@ index a69b4e4..dbccba5 100644 rt_genid_bump(net); ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_AH, 0); +diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c +index a8e4f26..25e5f40 100644 +--- a/net/ipv4/devinet.c ++++ b/net/ipv4/devinet.c +@@ -1763,7 +1763,7 @@ static int ipv4_doint_and_flush(ctl_table *ctl, int write, + #define DEVINET_SYSCTL_FLUSHING_ENTRY(attr, name) \ + DEVINET_SYSCTL_COMPLEX_ENTRY(attr, name, ipv4_doint_and_flush) + +-static struct devinet_sysctl_table { ++static const struct devinet_sysctl_table { + struct ctl_table_header *sysctl_header; + struct ctl_table devinet_vars[__IPV4_DEVCONF_MAX]; + } devinet_sysctl = { +@@ -1881,7 +1881,7 @@ static __net_init int devinet_init_net(struct net *net) + int err; + struct ipv4_devconf *all, *dflt; + #ifdef CONFIG_SYSCTL +- struct ctl_table *tbl = ctl_forward_entry; ++ ctl_table_no_const *tbl = NULL; + struct ctl_table_header *forw_hdr; + #endif + +@@ -1899,7 +1899,7 @@ static __net_init int devinet_init_net(struct net *net) + goto err_alloc_dflt; + + #ifdef CONFIG_SYSCTL +- tbl = kmemdup(tbl, sizeof(ctl_forward_entry), GFP_KERNEL); ++ tbl = kmemdup(ctl_forward_entry, sizeof(ctl_forward_entry), GFP_KERNEL); + if (tbl == NULL) + goto err_alloc_ctl; + +@@ -1919,7 +1919,10 @@ static __net_init int devinet_init_net(struct net *net) + goto err_reg_dflt; + + err = -ENOMEM; +- forw_hdr = register_net_sysctl(net, "net/ipv4", tbl); ++ if (!net_eq(net, &init_net)) ++ forw_hdr = register_net_sysctl(net, "net/ipv4", tbl); ++ else ++ forw_hdr = register_net_sysctl(net, "net/ipv4", ctl_forward_entry); + if (forw_hdr == NULL) + goto err_reg_ctl; + net->ipv4.forw_hdr = forw_hdr; +@@ -1935,8 +1938,7 @@ err_reg_ctl: + err_reg_dflt: + __devinet_sysctl_unregister(all); + err_reg_all: +- if (tbl != ctl_forward_entry) +- kfree(tbl); ++ kfree(tbl); + err_alloc_ctl: + #endif + if (dflt != &ipv4_devconf_dflt) diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 3b4f0cd..8cb864c 100644 --- a/net/ipv4/esp4.c @@ -80793,6 +84733,19 @@ index 4797a80..2bd54e9 100644 return nh->nh_saddr; } +diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c +index d0670f0..744ac80 100644 +--- a/net/ipv4/inet_connection_sock.c ++++ b/net/ipv4/inet_connection_sock.c +@@ -37,7 +37,7 @@ struct local_ports sysctl_local_ports __read_mostly = { + .range = { 32768, 61000 }, + }; + +-unsigned long *sysctl_local_reserved_ports; ++unsigned long sysctl_local_reserved_ports[65536 / 8 / sizeof(unsigned long)]; + EXPORT_SYMBOL(sysctl_local_reserved_ports); + + void inet_get_local_port_range(int *low, int *high) diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index fa3ae81..0dbe6b8 100644 --- a/net/ipv4/inet_hashtables.c @@ -80838,7 +84791,7 @@ index 000e3d2..5472da3 100644 secure_ip_id(daddr->addr.a4) : secure_ipv6_id(daddr->addr.a6)); diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c -index eb9d63a..50babc1 100644 +index eb9d63a..31c5372 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -322,7 +322,7 @@ static inline int ip_frag_too_far(struct ipq *qp) @@ -80850,6 +84803,75 @@ index eb9d63a..50babc1 100644 qp->rid = end; rc = qp->q.fragments && (end - start) > max; +@@ -789,12 +789,11 @@ static struct ctl_table ip4_frags_ctl_table[] = { + + static int __net_init ip4_frags_ns_ctl_register(struct net *net) + { +- struct ctl_table *table; ++ ctl_table_no_const *table = NULL; + struct ctl_table_header *hdr; + +- table = ip4_frags_ns_ctl_table; + if (!net_eq(net, &init_net)) { +- table = kmemdup(table, sizeof(ip4_frags_ns_ctl_table), GFP_KERNEL); ++ table = kmemdup(ip4_frags_ns_ctl_table, sizeof(ip4_frags_ns_ctl_table), GFP_KERNEL); + if (table == NULL) + goto err_alloc; + +@@ -805,9 +804,10 @@ static int __net_init ip4_frags_ns_ctl_register(struct net *net) + /* Don't export sysctls to unprivileged users */ + if (net->user_ns != &init_user_ns) + table[0].procname = NULL; +- } ++ hdr = register_net_sysctl(net, "net/ipv4", table); ++ } else ++ hdr = register_net_sysctl(net, "net/ipv4", ip4_frags_ns_ctl_table); + +- hdr = register_net_sysctl(net, "net/ipv4", table); + if (hdr == NULL) + goto err_reg; + +@@ -815,8 +815,7 @@ static int __net_init ip4_frags_ns_ctl_register(struct net *net) + return 0; + + err_reg: +- if (!net_eq(net, &init_net)) +- kfree(table); ++ kfree(table); + err_alloc: + return -ENOMEM; + } +diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c +index e81b1ca..6f3b5b9 100644 +--- a/net/ipv4/ip_gre.c ++++ b/net/ipv4/ip_gre.c +@@ -124,7 +124,7 @@ static bool log_ecn_error = true; + module_param(log_ecn_error, bool, 0644); + MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN"); + +-static struct rtnl_link_ops ipgre_link_ops __read_mostly; ++static struct rtnl_link_ops ipgre_link_ops; + static int ipgre_tunnel_init(struct net_device *dev); + static void ipgre_tunnel_setup(struct net_device *dev); + static int ipgre_tunnel_bind_dev(struct net_device *dev); +@@ -1756,7 +1756,7 @@ static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = { + [IFLA_GRE_PMTUDISC] = { .type = NLA_U8 }, + }; + +-static struct rtnl_link_ops ipgre_link_ops __read_mostly = { ++static struct rtnl_link_ops ipgre_link_ops = { + .kind = "gre", + .maxtype = IFLA_GRE_MAX, + .policy = ipgre_policy, +@@ -1769,7 +1769,7 @@ static struct rtnl_link_ops ipgre_link_ops __read_mostly = { + .fill_info = ipgre_fill_info, + }; + +-static struct rtnl_link_ops ipgre_tap_ops __read_mostly = { ++static struct rtnl_link_ops ipgre_tap_ops = { + .kind = "gretap", + .maxtype = IFLA_GRE_MAX, + .policy = ipgre_policy, diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index d9c4f11..02b82db 100644 --- a/net/ipv4/ip_sockglue.c @@ -80873,6 +84895,28 @@ index d9c4f11..02b82db 100644 msg.msg_controllen = len; msg.msg_flags = flags; +diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c +index c3a4233..1412161 100644 +--- a/net/ipv4/ip_vti.c ++++ b/net/ipv4/ip_vti.c +@@ -47,7 +47,7 @@ + #define HASH_SIZE 16 + #define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&(HASH_SIZE-1)) + +-static struct rtnl_link_ops vti_link_ops __read_mostly; ++static struct rtnl_link_ops vti_link_ops; + + static int vti_net_id __read_mostly; + struct vti_net { +@@ -886,7 +886,7 @@ static const struct nla_policy vti_policy[IFLA_VTI_MAX + 1] = { + [IFLA_VTI_REMOTE] = { .len = FIELD_SIZEOF(struct iphdr, daddr) }, + }; + +-static struct rtnl_link_ops vti_link_ops __read_mostly = { ++static struct rtnl_link_ops vti_link_ops = { + .kind = "vti", + .maxtype = IFLA_VTI_MAX, + .policy = vti_policy, diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 9a46dae..5f793a0 100644 --- a/net/ipv4/ipcomp.c @@ -80917,6 +84961,28 @@ index a2e50ae..e152b7c 100644 set_fs(oldfs); return res; } +diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c +index 191fc24..1b3b804 100644 +--- a/net/ipv4/ipip.c ++++ b/net/ipv4/ipip.c +@@ -138,7 +138,7 @@ struct ipip_net { + static int ipip_tunnel_init(struct net_device *dev); + static void ipip_tunnel_setup(struct net_device *dev); + static void ipip_dev_free(struct net_device *dev); +-static struct rtnl_link_ops ipip_link_ops __read_mostly; ++static struct rtnl_link_ops ipip_link_ops; + + static struct rtnl_link_stats64 *ipip_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 *tot) +@@ -972,7 +972,7 @@ static const struct nla_policy ipip_policy[IFLA_IPTUN_MAX + 1] = { + [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 }, + }; + +-static struct rtnl_link_ops ipip_link_ops __read_mostly = { ++static struct rtnl_link_ops ipip_link_ops = { + .kind = "ipip", + .maxtype = IFLA_IPTUN_MAX, + .policy = ipip_policy, diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 3ea4127..849297b 100644 --- a/net/ipv4/netfilter/arp_tables.c @@ -81084,9 +85150,52 @@ index 6f08991..55867ad 100644 static int raw_seq_show(struct seq_file *seq, void *v) diff --git a/net/ipv4/route.c b/net/ipv4/route.c -index a0fcc47..5949bba1 100644 +index a0fcc47..32e2c89 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c +@@ -2552,34 +2552,34 @@ static struct ctl_table ipv4_route_flush_table[] = { + .maxlen = sizeof(int), + .mode = 0200, + .proc_handler = ipv4_sysctl_rtcache_flush, ++ .extra1 = &init_net, + }, + { }, + }; + + static __net_init int sysctl_route_net_init(struct net *net) + { +- struct ctl_table *tbl; ++ ctl_table_no_const *tbl = NULL; + +- tbl = ipv4_route_flush_table; + if (!net_eq(net, &init_net)) { +- tbl = kmemdup(tbl, sizeof(ipv4_route_flush_table), GFP_KERNEL); ++ tbl = kmemdup(ipv4_route_flush_table, sizeof(ipv4_route_flush_table), GFP_KERNEL); + if (tbl == NULL) + goto err_dup; + + /* Don't export sysctls to unprivileged users */ + if (net->user_ns != &init_user_ns) + tbl[0].procname = NULL; +- } +- tbl[0].extra1 = net; ++ tbl[0].extra1 = net; ++ net->ipv4.route_hdr = register_net_sysctl(net, "net/ipv4/route", tbl); ++ } else ++ net->ipv4.route_hdr = register_net_sysctl(net, "net/ipv4/route", ipv4_route_flush_table); + +- net->ipv4.route_hdr = register_net_sysctl(net, "net/ipv4/route", tbl); + if (net->ipv4.route_hdr == NULL) + goto err_reg; + return 0; + + err_reg: +- if (tbl != ipv4_route_flush_table) +- kfree(tbl); ++ kfree(tbl); + err_dup: + return -ENOMEM; + } @@ -2602,7 +2602,7 @@ static __net_initdata struct pernet_operations sysctl_route_ops = { static __net_init int rt_genid_init(struct net *net) @@ -81096,6 +85205,146 @@ index a0fcc47..5949bba1 100644 get_random_bytes(&net->ipv4.dev_addr_genid, sizeof(net->ipv4.dev_addr_genid)); return 0; +diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c +index d84400b..62e066e 100644 +--- a/net/ipv4/sysctl_net_ipv4.c ++++ b/net/ipv4/sysctl_net_ipv4.c +@@ -54,7 +54,7 @@ static int ipv4_local_port_range(ctl_table *table, int write, + { + int ret; + int range[2]; +- ctl_table tmp = { ++ ctl_table_no_const tmp = { + .data = &range, + .maxlen = sizeof(range), + .mode = table->mode, +@@ -107,7 +107,7 @@ static int ipv4_ping_group_range(ctl_table *table, int write, + int ret; + gid_t urange[2]; + kgid_t low, high; +- ctl_table tmp = { ++ ctl_table_no_const tmp = { + .data = &urange, + .maxlen = sizeof(urange), + .mode = table->mode, +@@ -138,7 +138,7 @@ static int proc_tcp_congestion_control(ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { + char val[TCP_CA_NAME_MAX]; +- ctl_table tbl = { ++ ctl_table_no_const tbl = { + .data = val, + .maxlen = TCP_CA_NAME_MAX, + }; +@@ -157,7 +157,7 @@ static int proc_tcp_available_congestion_control(ctl_table *ctl, + void __user *buffer, size_t *lenp, + loff_t *ppos) + { +- ctl_table tbl = { .maxlen = TCP_CA_BUF_MAX, }; ++ ctl_table_no_const tbl = { .maxlen = TCP_CA_BUF_MAX, }; + int ret; + + tbl.data = kmalloc(tbl.maxlen, GFP_USER); +@@ -174,7 +174,7 @@ static int proc_allowed_congestion_control(ctl_table *ctl, + void __user *buffer, size_t *lenp, + loff_t *ppos) + { +- ctl_table tbl = { .maxlen = TCP_CA_BUF_MAX }; ++ ctl_table_no_const tbl = { .maxlen = TCP_CA_BUF_MAX }; + int ret; + + tbl.data = kmalloc(tbl.maxlen, GFP_USER); +@@ -200,15 +200,17 @@ static int ipv4_tcp_mem(ctl_table *ctl, int write, + struct mem_cgroup *memcg; + #endif + +- ctl_table tmp = { ++ ctl_table_no_const tmp = { + .data = &vec, + .maxlen = sizeof(vec), + .mode = ctl->mode, + }; + + if (!write) { +- ctl->data = &net->ipv4.sysctl_tcp_mem; +- return proc_doulongvec_minmax(ctl, write, buffer, lenp, ppos); ++ ctl_table_no_const tcp_mem = *ctl; ++ ++ tcp_mem.data = &net->ipv4.sysctl_tcp_mem; ++ return proc_doulongvec_minmax(&tcp_mem, write, buffer, lenp, ppos); + } + + ret = proc_doulongvec_minmax(&tmp, write, buffer, lenp, ppos); +@@ -235,7 +237,7 @@ static int ipv4_tcp_mem(ctl_table *ctl, int write, + int proc_tcp_fastopen_key(ctl_table *ctl, int write, void __user *buffer, + size_t *lenp, loff_t *ppos) + { +- ctl_table tbl = { .maxlen = (TCP_FASTOPEN_KEY_LENGTH * 2 + 10) }; ++ ctl_table_no_const tbl = { .maxlen = (TCP_FASTOPEN_KEY_LENGTH * 2 + 10) }; + struct tcp_fastopen_context *ctxt; + int ret; + u32 user_key[4]; /* 16 bytes, matching TCP_FASTOPEN_KEY_LENGTH */ +@@ -476,7 +478,7 @@ static struct ctl_table ipv4_table[] = { + }, + { + .procname = "ip_local_reserved_ports", +- .data = NULL, /* initialized in sysctl_ipv4_init */ ++ .data = sysctl_local_reserved_ports, + .maxlen = 65536, + .mode = 0644, + .proc_handler = proc_do_large_bitmap, +@@ -860,11 +862,10 @@ static struct ctl_table ipv4_net_table[] = { + + static __net_init int ipv4_sysctl_init_net(struct net *net) + { +- struct ctl_table *table; ++ ctl_table_no_const *table = NULL; + +- table = ipv4_net_table; + if (!net_eq(net, &init_net)) { +- table = kmemdup(table, sizeof(ipv4_net_table), GFP_KERNEL); ++ table = kmemdup(ipv4_net_table, sizeof(ipv4_net_table), GFP_KERNEL); + if (table == NULL) + goto err_alloc; + +@@ -897,15 +898,17 @@ static __net_init int ipv4_sysctl_init_net(struct net *net) + + tcp_init_mem(net); + +- net->ipv4.ipv4_hdr = register_net_sysctl(net, "net/ipv4", table); ++ if (!net_eq(net, &init_net)) ++ net->ipv4.ipv4_hdr = register_net_sysctl(net, "net/ipv4", table); ++ else ++ net->ipv4.ipv4_hdr = register_net_sysctl(net, "net/ipv4", ipv4_net_table); + if (net->ipv4.ipv4_hdr == NULL) + goto err_reg; + + return 0; + + err_reg: +- if (!net_eq(net, &init_net)) +- kfree(table); ++ kfree(table); + err_alloc: + return -ENOMEM; + } +@@ -927,16 +930,6 @@ static __net_initdata struct pernet_operations ipv4_sysctl_ops = { + static __init int sysctl_ipv4_init(void) + { + struct ctl_table_header *hdr; +- struct ctl_table *i; +- +- for (i = ipv4_table; i->procname; i++) { +- if (strcmp(i->procname, "ip_local_reserved_ports") == 0) { +- i->data = sysctl_local_reserved_ports; +- break; +- } +- } +- if (!i->procname) +- return -EINVAL; + + hdr = register_net_sysctl(&init_net, "net/ipv4", ipv4_table); + if (hdr == NULL) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index ad70a96..50cb55b 100644 --- a/net/ipv4/tcp_input.c @@ -81381,7 +85630,7 @@ index 1f4d405..3524677 100644 int udp4_seq_show(struct seq_file *seq, void *v) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index 1b5d8cb..2e8c2d9 100644 +index 1b5d8cb..ffb0833 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2272,7 +2272,7 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg) @@ -81393,10 +85642,50 @@ index 1b5d8cb..2e8c2d9 100644 if (ops->ndo_do_ioctl) { mm_segment_t oldfs = get_fs(); +@@ -4388,7 +4388,7 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write, + int *valp = ctl->data; + int val = *valp; + loff_t pos = *ppos; +- ctl_table lctl; ++ ctl_table_no_const lctl; + int ret; + + /* +@@ -4470,7 +4470,7 @@ int addrconf_sysctl_disable(ctl_table *ctl, int write, + int *valp = ctl->data; + int val = *valp; + loff_t pos = *ppos; +- ctl_table lctl; ++ ctl_table_no_const lctl; + int ret; + + /* +diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c +index fff5bdd..15194fb 100644 +--- a/net/ipv6/icmp.c ++++ b/net/ipv6/icmp.c +@@ -973,7 +973,7 @@ ctl_table ipv6_icmp_table_template[] = { + + struct ctl_table * __net_init ipv6_icmp_sysctl_init(struct net *net) + { +- struct ctl_table *table; ++ ctl_table_no_const *table; + + table = kmemdup(ipv6_icmp_table_template, + sizeof(ipv6_icmp_table_template), diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c -index 131dd09..7647ada 100644 +index 131dd09..f7ed64f 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c +@@ -73,7 +73,7 @@ struct ip6gre_net { + struct net_device *fb_tunnel_dev; + }; + +-static struct rtnl_link_ops ip6gre_link_ops __read_mostly; ++static struct rtnl_link_ops ip6gre_link_ops; + static int ip6gre_tunnel_init(struct net_device *dev); + static void ip6gre_tunnel_setup(struct net_device *dev); + static void ip6gre_tunnel_link(struct ip6gre_net *ign, struct ip6_tnl *t); @@ -1337,7 +1337,7 @@ static void ip6gre_fb_tunnel_init(struct net_device *dev) } @@ -81406,6 +85695,46 @@ index 131dd09..7647ada 100644 .handler = ip6gre_rcv, .err_handler = ip6gre_err, .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, +@@ -1671,7 +1671,7 @@ static const struct nla_policy ip6gre_policy[IFLA_GRE_MAX + 1] = { + [IFLA_GRE_FLAGS] = { .type = NLA_U32 }, + }; + +-static struct rtnl_link_ops ip6gre_link_ops __read_mostly = { ++static struct rtnl_link_ops ip6gre_link_ops = { + .kind = "ip6gre", + .maxtype = IFLA_GRE_MAX, + .policy = ip6gre_policy, +@@ -1684,7 +1684,7 @@ static struct rtnl_link_ops ip6gre_link_ops __read_mostly = { + .fill_info = ip6gre_fill_info, + }; + +-static struct rtnl_link_ops ip6gre_tap_ops __read_mostly = { ++static struct rtnl_link_ops ip6gre_tap_ops = { + .kind = "ip6gretap", + .maxtype = IFLA_GRE_MAX, + .policy = ip6gre_policy, +diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c +index a14f28b..b4b8956 100644 +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -87,7 +87,7 @@ static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2) + + static int ip6_tnl_dev_init(struct net_device *dev); + static void ip6_tnl_dev_setup(struct net_device *dev); +-static struct rtnl_link_ops ip6_link_ops __read_mostly; ++static struct rtnl_link_ops ip6_link_ops; + + static int ip6_tnl_net_id __read_mostly; + struct ip6_tnl_net { +@@ -1686,7 +1686,7 @@ static const struct nla_policy ip6_tnl_policy[IFLA_IPTUN_MAX + 1] = { + [IFLA_IPTUN_PROTO] = { .type = NLA_U8 }, + }; + +-static struct rtnl_link_ops ip6_link_ops __read_mostly = { ++static struct rtnl_link_ops ip6_link_ops = { + .kind = "ip6tnl", + .maxtype = IFLA_IPTUN_MAX, + .policy = ip6_tnl_policy, diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index d1e2e8e..51c19ae 100644 --- a/net/ipv6/ipv6_sockglue.c @@ -81468,6 +85797,48 @@ index 125a90d..2a11f36 100644 break; case IP6T_SO_GET_ENTRIES: +diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c +index 3dacecc..2939087 100644 +--- a/net/ipv6/netfilter/nf_conntrack_reasm.c ++++ b/net/ipv6/netfilter/nf_conntrack_reasm.c +@@ -87,12 +87,11 @@ static struct ctl_table nf_ct_frag6_sysctl_table[] = { + + static int nf_ct_frag6_sysctl_register(struct net *net) + { +- struct ctl_table *table; ++ ctl_table_no_const *table = NULL; + struct ctl_table_header *hdr; + +- table = nf_ct_frag6_sysctl_table; + if (!net_eq(net, &init_net)) { +- table = kmemdup(table, sizeof(nf_ct_frag6_sysctl_table), ++ table = kmemdup(nf_ct_frag6_sysctl_table, sizeof(nf_ct_frag6_sysctl_table), + GFP_KERNEL); + if (table == NULL) + goto err_alloc; +@@ -100,9 +99,9 @@ static int nf_ct_frag6_sysctl_register(struct net *net) + table[0].data = &net->ipv6.frags.high_thresh; + table[1].data = &net->ipv6.frags.low_thresh; + table[2].data = &net->ipv6.frags.timeout; +- } +- +- hdr = register_net_sysctl(net, "net/netfilter", table); ++ hdr = register_net_sysctl(net, "net/netfilter", table); ++ } else ++ hdr = register_net_sysctl(net, "net/netfilter", nf_ct_frag6_sysctl_table); + if (hdr == NULL) + goto err_reg; + +@@ -110,8 +109,7 @@ static int nf_ct_frag6_sysctl_register(struct net *net) + return 0; + + err_reg: +- if (!net_eq(net, &init_net)) +- kfree(table); ++ kfree(table); + err_alloc: + return -ENOMEM; + } diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 70fa814..d70c28c 100644 --- a/net/ipv6/raw.c @@ -81552,6 +85923,96 @@ index 70fa814..d70c28c 100644 } static int raw6_seq_show(struct seq_file *seq, void *v) +diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c +index e5253ec..0410257 100644 +--- a/net/ipv6/reassembly.c ++++ b/net/ipv6/reassembly.c +@@ -604,12 +604,11 @@ static struct ctl_table ip6_frags_ctl_table[] = { + + static int __net_init ip6_frags_ns_sysctl_register(struct net *net) + { +- struct ctl_table *table; ++ ctl_table_no_const *table = NULL; + struct ctl_table_header *hdr; + +- table = ip6_frags_ns_ctl_table; + if (!net_eq(net, &init_net)) { +- table = kmemdup(table, sizeof(ip6_frags_ns_ctl_table), GFP_KERNEL); ++ table = kmemdup(ip6_frags_ns_ctl_table, sizeof(ip6_frags_ns_ctl_table), GFP_KERNEL); + if (table == NULL) + goto err_alloc; + +@@ -620,9 +619,10 @@ static int __net_init ip6_frags_ns_sysctl_register(struct net *net) + /* Don't export sysctls to unprivileged users */ + if (net->user_ns != &init_user_ns) + table[0].procname = NULL; +- } ++ hdr = register_net_sysctl(net, "net/ipv6", table); ++ } else ++ hdr = register_net_sysctl(net, "net/ipv6", ip6_frags_ns_ctl_table); + +- hdr = register_net_sysctl(net, "net/ipv6", table); + if (hdr == NULL) + goto err_reg; + +@@ -630,8 +630,7 @@ static int __net_init ip6_frags_ns_sysctl_register(struct net *net) + return 0; + + err_reg: +- if (!net_eq(net, &init_net)) +- kfree(table); ++ kfree(table); + err_alloc: + return -ENOMEM; + } +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index 6f9f7b6..2306d63 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -2965,7 +2965,7 @@ ctl_table ipv6_route_table_template[] = { + + struct ctl_table * __net_init ipv6_route_sysctl_init(struct net *net) + { +- struct ctl_table *table; ++ ctl_table_no_const *table; + + table = kmemdup(ipv6_route_table_template, + sizeof(ipv6_route_table_template), +diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c +index cfba99b..20ca511 100644 +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -72,7 +72,7 @@ MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN"); + static int ipip6_tunnel_init(struct net_device *dev); + static void ipip6_tunnel_setup(struct net_device *dev); + static void ipip6_dev_free(struct net_device *dev); +-static struct rtnl_link_ops sit_link_ops __read_mostly; ++static struct rtnl_link_ops sit_link_ops; + + static int sit_net_id __read_mostly; + struct sit_net { +@@ -1463,7 +1463,7 @@ static const struct nla_policy ipip6_policy[IFLA_IPTUN_MAX + 1] = { + #endif + }; + +-static struct rtnl_link_ops sit_link_ops __read_mostly = { ++static struct rtnl_link_ops sit_link_ops = { + .kind = "sit", + .maxtype = IFLA_IPTUN_MAX, + .policy = ipip6_policy, +diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c +index e85c48b..b8268d3 100644 +--- a/net/ipv6/sysctl_net_ipv6.c ++++ b/net/ipv6/sysctl_net_ipv6.c +@@ -40,7 +40,7 @@ static ctl_table ipv6_rotable[] = { + + static int __net_init ipv6_sysctl_net_init(struct net *net) + { +- struct ctl_table *ipv6_table; ++ ctl_table_no_const *ipv6_table; + struct ctl_table *ipv6_route_table; + struct ctl_table *ipv6_icmp_table; + int err; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 4f435371..5de9da7 100644 --- a/net/ipv6/tcp_ipv6.c @@ -81749,6 +86210,24 @@ index a68c88c..d55b0c5 100644 seq_printf(m, "Max data size: %d\n", self->max_data_size); seq_printf(m, "Max header size: %d\n", self->max_header_size); +diff --git a/net/irda/iriap.c b/net/irda/iriap.c +index e71e85b..29340a9 100644 +--- a/net/irda/iriap.c ++++ b/net/irda/iriap.c +@@ -495,8 +495,11 @@ static void iriap_getvaluebyclass_confirm(struct iriap_cb *self, + /* case CS_ISO_8859_9: */ + /* case CS_UNICODE: */ + default: +- IRDA_DEBUG(0, "%s(), charset %s, not supported\n", +- __func__, ias_charset_types[charset]); ++ IRDA_DEBUG(0, "%s(), charset [%d] %s, not supported\n", ++ __func__, charset, ++ charset < ARRAY_SIZE(ias_charset_types) ? ++ ias_charset_types[charset] : ++ "(unknown)"); + + /* Aborting, close connection! */ + iriap_disconnect_request(self); diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index cd6f7a9..e63fe89 100644 --- a/net/iucv/af_iucv.c @@ -81796,6 +86275,18 @@ index 5b426a6..970032b 100644 } while (!res); return res; } +diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c +index 716605c..044e9e1 100644 +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -355,6 +355,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh + l2tp_xmit_skb(session, skb, session->hdr_len); + + sock_put(ps->tunnel_sock); ++ sock_put(sk); + + return error; + diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 0479c64..d031db6 100644 --- a/net/mac80211/cfg.c @@ -82022,6 +86513,19 @@ index 3259697..54d5393 100644 obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o obj-$(CONFIG_NETFILTER_XT_MATCH_HL) += xt_hl.o +diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c +index 6d6d8f2..a676749 100644 +--- a/net/netfilter/ipset/ip_set_core.c ++++ b/net/netfilter/ipset/ip_set_core.c +@@ -1800,7 +1800,7 @@ done: + return ret; + } + +-static struct nf_sockopt_ops so_set __read_mostly = { ++static struct nf_sockopt_ops so_set = { + .pf = PF_INET, + .get_optmin = SO_IP_SET, + .get_optmax = SO_IP_SET + 1, diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index 30e764a..c3b6a9d 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c @@ -82076,7 +86580,7 @@ index 47edf5a..235b07d 100644 if (ipvs->sync_state & IP_VS_STATE_MASTER) ip_vs_sync_conn(net, cp, pkts); diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c -index ec664cb..cd576ab 100644 +index ec664cb..7f34a77 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -787,7 +787,7 @@ __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest, @@ -82088,6 +86592,15 @@ index ec664cb..cd576ab 100644 /* bind the service */ if (!dest->svc) { +@@ -1688,7 +1688,7 @@ proc_do_sync_ports(ctl_table *table, int write, + * align with netns init in ip_vs_control_net_init() + */ + +-static struct ctl_table vs_vars[] = { ++static ctl_table_no_const vs_vars[] __read_only = { + { + .procname = "amemthresh", + .maxlen = sizeof(int), @@ -2081,7 +2081,7 @@ static int ip_vs_info_seq_show(struct seq_file *seq, void *v) " %-7s %-6d %-10d %-10d\n", &dest->addr.in6, @@ -82124,6 +86637,41 @@ index ec664cb..cd576ab 100644 IP_VS_CONN_F_FWD_MASK)) || nla_put_u32(skb, IPVS_DEST_ATTR_WEIGHT, atomic_read(&dest->weight)) || +@@ -3688,7 +3688,7 @@ static int __net_init ip_vs_control_net_init_sysctl(struct net *net) + { + int idx; + struct netns_ipvs *ipvs = net_ipvs(net); +- struct ctl_table *tbl; ++ ctl_table_no_const *tbl; + + atomic_set(&ipvs->dropentry, 0); + spin_lock_init(&ipvs->dropentry_lock); +diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c +index fdd89b9..bd96aa9 100644 +--- a/net/netfilter/ipvs/ip_vs_lblc.c ++++ b/net/netfilter/ipvs/ip_vs_lblc.c +@@ -115,7 +115,7 @@ struct ip_vs_lblc_table { + * IPVS LBLC sysctl table + */ + #ifdef CONFIG_SYSCTL +-static ctl_table vs_vars_table[] = { ++static ctl_table_no_const vs_vars_table[] __read_only = { + { + .procname = "lblc_expiration", + .data = NULL, +diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c +index c03b6a3..8ce3681 100644 +--- a/net/netfilter/ipvs/ip_vs_lblcr.c ++++ b/net/netfilter/ipvs/ip_vs_lblcr.c +@@ -288,7 +288,7 @@ struct ip_vs_lblcr_table { + * IPVS LBLCR sysctl table + */ + +-static ctl_table vs_vars_table[] = { ++static ctl_table_no_const vs_vars_table[] __read_only = { + { + .procname = "lblcr_expiration", + .data = NULL, diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c index 44fd10c..2a163b3 100644 --- a/net/netfilter/ipvs/ip_vs_sync.c @@ -82177,6 +86725,19 @@ index ee6b7a9..f9a89f6 100644 goto out; } +diff --git a/net/netfilter/nf_conntrack_acct.c b/net/netfilter/nf_conntrack_acct.c +index 7df424e..a527b02 100644 +--- a/net/netfilter/nf_conntrack_acct.c ++++ b/net/netfilter/nf_conntrack_acct.c +@@ -60,7 +60,7 @@ static struct nf_ct_ext_type acct_extend __read_mostly = { + #ifdef CONFIG_SYSCTL + static int nf_conntrack_acct_init_sysctl(struct net *net) + { +- struct ctl_table *table; ++ ctl_table_no_const *table; + + table = kmemdup(acct_sysctl_table, sizeof(acct_sysctl_table), + GFP_KERNEL); diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index e4a0c4f..c263f28 100644 --- a/net/netfilter/nf_conntrack_core.c @@ -82204,6 +86765,126 @@ index e4a0c4f..c263f28 100644 if (!net->ct.slabname) { ret = -ENOMEM; goto err_slabname; +diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c +index faa978f..1afb18f 100644 +--- a/net/netfilter/nf_conntrack_ecache.c ++++ b/net/netfilter/nf_conntrack_ecache.c +@@ -186,7 +186,7 @@ static struct nf_ct_ext_type event_extend __read_mostly = { + #ifdef CONFIG_SYSCTL + static int nf_conntrack_event_init_sysctl(struct net *net) + { +- struct ctl_table *table; ++ ctl_table_no_const *table; + + table = kmemdup(event_sysctl_table, sizeof(event_sysctl_table), + GFP_KERNEL); +diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c +index 884f2b3..d53b33a 100644 +--- a/net/netfilter/nf_conntrack_helper.c ++++ b/net/netfilter/nf_conntrack_helper.c +@@ -55,7 +55,7 @@ static struct ctl_table helper_sysctl_table[] = { + + static int nf_conntrack_helper_init_sysctl(struct net *net) + { +- struct ctl_table *table; ++ ctl_table_no_const *table; + + table = kmemdup(helper_sysctl_table, sizeof(helper_sysctl_table), + GFP_KERNEL); +diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c +index 51e928d..72a413a 100644 +--- a/net/netfilter/nf_conntrack_proto.c ++++ b/net/netfilter/nf_conntrack_proto.c +@@ -51,7 +51,7 @@ nf_ct_register_sysctl(struct net *net, + + static void + nf_ct_unregister_sysctl(struct ctl_table_header **header, +- struct ctl_table **table, ++ ctl_table_no_const **table, + unsigned int users) + { + if (users > 0) +diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c +index e7185c6..4ad6c9c 100644 +--- a/net/netfilter/nf_conntrack_standalone.c ++++ b/net/netfilter/nf_conntrack_standalone.c +@@ -470,7 +470,7 @@ static ctl_table nf_ct_netfilter_table[] = { + + static int nf_conntrack_standalone_init_sysctl(struct net *net) + { +- struct ctl_table *table; ++ ctl_table_no_const *table; + + if (net_eq(net, &init_net)) { + nf_ct_netfilter_header = +diff --git a/net/netfilter/nf_conntrack_timestamp.c b/net/netfilter/nf_conntrack_timestamp.c +index 7ea8026..bc9512d 100644 +--- a/net/netfilter/nf_conntrack_timestamp.c ++++ b/net/netfilter/nf_conntrack_timestamp.c +@@ -42,7 +42,7 @@ static struct nf_ct_ext_type tstamp_extend __read_mostly = { + #ifdef CONFIG_SYSCTL + static int nf_conntrack_tstamp_init_sysctl(struct net *net) + { +- struct ctl_table *table; ++ ctl_table_no_const *table; + + table = kmemdup(tstamp_sysctl_table, sizeof(tstamp_sysctl_table), + GFP_KERNEL); +diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c +index 9e31269..bc4c1b7 100644 +--- a/net/netfilter/nf_log.c ++++ b/net/netfilter/nf_log.c +@@ -215,7 +215,7 @@ static const struct file_operations nflog_file_ops = { + + #ifdef CONFIG_SYSCTL + static char nf_log_sysctl_fnames[NFPROTO_NUMPROTO-NFPROTO_UNSPEC][3]; +-static struct ctl_table nf_log_sysctl_table[NFPROTO_NUMPROTO+1]; ++static ctl_table_no_const nf_log_sysctl_table[NFPROTO_NUMPROTO+1] __read_only; + static struct ctl_table_header *nf_log_dir_header; + + static int nf_log_proc_dostring(ctl_table *table, int write, +@@ -246,14 +246,16 @@ static int nf_log_proc_dostring(ctl_table *table, int write, + rcu_assign_pointer(nf_loggers[tindex], logger); + mutex_unlock(&nf_log_mutex); + } else { ++ ctl_table_no_const nf_log_table = *table; ++ + mutex_lock(&nf_log_mutex); + logger = rcu_dereference_protected(nf_loggers[tindex], + lockdep_is_held(&nf_log_mutex)); + if (!logger) +- table->data = "NONE"; ++ nf_log_table.data = "NONE"; + else +- table->data = logger->name; +- r = proc_dostring(table, write, buffer, lenp, ppos); ++ nf_log_table.data = logger->name; ++ r = proc_dostring(&nf_log_table, write, buffer, lenp, ppos); + mutex_unlock(&nf_log_mutex); + } + +diff --git a/net/netfilter/nf_sockopt.c b/net/netfilter/nf_sockopt.c +index f042ae5..30ea486 100644 +--- a/net/netfilter/nf_sockopt.c ++++ b/net/netfilter/nf_sockopt.c +@@ -45,7 +45,7 @@ int nf_register_sockopt(struct nf_sockopt_ops *reg) + } + } + +- list_add(®->list, &nf_sockopts); ++ pax_list_add((struct list_head *)®->list, &nf_sockopts); + out: + mutex_unlock(&nf_sockopt_mutex); + return ret; +@@ -55,7 +55,7 @@ EXPORT_SYMBOL(nf_register_sockopt); + void nf_unregister_sockopt(struct nf_sockopt_ops *reg) + { + mutex_lock(&nf_sockopt_mutex); +- list_del(®->list); ++ pax_list_del((struct list_head *)®->list); + mutex_unlock(&nf_sockopt_mutex); + } + EXPORT_SYMBOL(nf_unregister_sockopt); diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 92fd8ec..3f6ea4b 100644 --- a/net/netfilter/nfnetlink_log.c @@ -82339,6 +87020,48 @@ index c0353d5..fcb0270 100644 sock_i_ino(s) ); +diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c +index f2aabb6..2e5e66e 100644 +--- a/net/netlink/genetlink.c ++++ b/net/netlink/genetlink.c +@@ -295,18 +295,20 @@ int genl_register_ops(struct genl_family *family, struct genl_ops *ops) + goto errout; + } + ++ pax_open_kernel(); + if (ops->dumpit) +- ops->flags |= GENL_CMD_CAP_DUMP; ++ *(unsigned int *)&ops->flags |= GENL_CMD_CAP_DUMP; + if (ops->doit) +- ops->flags |= GENL_CMD_CAP_DO; ++ *(unsigned int *)&ops->flags |= GENL_CMD_CAP_DO; + if (ops->policy) +- ops->flags |= GENL_CMD_CAP_HASPOL; ++ *(unsigned int *)&ops->flags |= GENL_CMD_CAP_HASPOL; ++ pax_close_kernel(); + + genl_lock(); +- list_add_tail(&ops->ops_list, &family->ops_list); ++ pax_list_add_tail((struct list_head *)&ops->ops_list, &family->ops_list); + genl_unlock(); + +- genl_ctrl_event(CTRL_CMD_NEWOPS, ops); ++ genl_ctrl_event(CTRL_CMD_NEWOPS, (void *)ops); + err = 0; + errout: + return err; +@@ -336,9 +338,9 @@ int genl_unregister_ops(struct genl_family *family, struct genl_ops *ops) + genl_lock(); + list_for_each_entry(rc, &family->ops_list, ops_list) { + if (rc == ops) { +- list_del(&ops->ops_list); ++ pax_list_del((struct list_head *)&ops->ops_list); + genl_unlock(); +- genl_ctrl_event(CTRL_CMD_DELOPS, ops); ++ genl_ctrl_event(CTRL_CMD_DELOPS, (void *)ops); + return 0; + } + } diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 7261eb8..44e8ac6 100644 --- a/net/netrom/af_netrom.c @@ -82484,6 +87207,19 @@ index b7e9827..c264c85 100644 } seq_printf(seq, "%*s\n", 127 - len, ""); return 0; +diff --git a/net/phonet/sysctl.c b/net/phonet/sysctl.c +index d6bbbbd..61561e4 100644 +--- a/net/phonet/sysctl.c ++++ b/net/phonet/sysctl.c +@@ -67,7 +67,7 @@ static int proc_local_port_range(ctl_table *table, int write, + { + int ret; + int range[2] = {local_port_range[0], local_port_range[1]}; +- ctl_table tmp = { ++ ctl_table_no_const tmp = { + .data = &range, + .maxlen = sizeof(range), + .mode = table->mode, diff --git a/net/rds/cong.c b/net/rds/cong.c index e5b65ac..f3b6fb7 100644 --- a/net/rds/cong.c @@ -82611,6 +87347,33 @@ index 4503335..db566b4 100644 } #endif +diff --git a/net/rds/message.c b/net/rds/message.c +index f0a4658..aff589c 100644 +--- a/net/rds/message.c ++++ b/net/rds/message.c +@@ -197,6 +197,9 @@ struct rds_message *rds_message_alloc(unsigned int extra_len, gfp_t gfp) + { + struct rds_message *rm; + ++ if (extra_len > KMALLOC_MAX_SIZE - sizeof(struct rds_message)) ++ return NULL; ++ + rm = kzalloc(sizeof(struct rds_message) + extra_len, gfp); + if (!rm) + goto out; +diff --git a/net/rds/rds.h b/net/rds/rds.h +index ec1d731..90a3a8d 100644 +--- a/net/rds/rds.h ++++ b/net/rds/rds.h +@@ -449,7 +449,7 @@ struct rds_transport { + void (*sync_mr)(void *trans_private, int direction); + void (*free_mr)(void *trans_private, int invalidate); + void (*flush_mrs)(void); +-}; ++} __do_const; + + struct rds_sock { + struct sock rs_sk; diff --git a/net/rds/tcp.c b/net/rds/tcp.c index edac9ef..16bcb98 100644 --- a/net/rds/tcp.c @@ -82898,15 +87661,33 @@ index f226709..0e735a8 100644 ret = kernel_sendmsg(conn->trans->local->socket, &msg, iov, 3, len); diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c -index 391a245..8f6a898 100644 +index 391a245..296b3d7 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c +@@ -981,7 +981,7 @@ static const struct inet6_protocol sctpv6_protocol = { + .flags = INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL, + }; + +-static struct sctp_af sctp_af_inet6 = { ++static struct sctp_af sctp_af_inet6 __read_only = { + .sa_family = AF_INET6, + .sctp_xmit = sctp_v6_xmit, + .setsockopt = ipv6_setsockopt, +@@ -1013,7 +1013,7 @@ static struct sctp_af sctp_af_inet6 = { + #endif + }; + +-static struct sctp_pf sctp_pf_inet6 = { ++static struct sctp_pf sctp_pf_inet6 __read_only = { + .event_msgname = sctp_inet6_event_msgname, + .skb_msgname = sctp_inet6_skb_msgname, + .af_supported = sctp_inet6_af_supported, @@ -1038,7 +1038,7 @@ void sctp_v6_pf_init(void) void sctp_v6_pf_exit(void) { - list_del(&sctp_af_inet6.list); -+ pax_list_del((struct list_head *)&sctp_af_inet6.list); ++ pax_list_del(&sctp_af_inet6.list); } /* Initialize IPv6 support and register with socket layer. */ @@ -82925,33 +87706,63 @@ index 8c19e97..16264b8 100644 assoc->assoc_id, assoc->sndbuf_used, diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c -index f898b1c..60bf8f2 100644 +index f898b1c..a2d0fe8 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -834,8 +834,10 @@ int sctp_register_af(struct sctp_af *af) return 0; } -- INIT_LIST_HEAD(&af->list); -- list_add_tail(&af->list, &sctp_address_families); + pax_open_kernel(); -+ INIT_LIST_HEAD((struct list_head *)&af->list); + INIT_LIST_HEAD(&af->list); +- list_add_tail(&af->list, &sctp_address_families); + pax_close_kernel(); -+ pax_list_add_tail((struct list_head *)&af->list, &sctp_address_families); ++ pax_list_add_tail(&af->list, &sctp_address_families); return 1; } +@@ -966,7 +968,7 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, + + static struct sctp_af sctp_af_inet; + +-static struct sctp_pf sctp_pf_inet = { ++static struct sctp_pf sctp_pf_inet __read_only = { + .event_msgname = sctp_inet_event_msgname, + .skb_msgname = sctp_inet_skb_msgname, + .af_supported = sctp_inet_af_supported, +@@ -1037,7 +1039,7 @@ static const struct net_protocol sctp_protocol = { + }; + + /* IPv4 address related functions. */ +-static struct sctp_af sctp_af_inet = { ++static struct sctp_af sctp_af_inet __read_only = { + .sa_family = AF_INET, + .sctp_xmit = sctp_v4_xmit, + .setsockopt = ip_setsockopt, @@ -1122,7 +1124,7 @@ static void sctp_v4_pf_init(void) static void sctp_v4_pf_exit(void) { - list_del(&sctp_af_inet.list); -+ pax_list_del((struct list_head *)&sctp_af_inet.list); ++ pax_list_del(&sctp_af_inet.list); } static int sctp_v4_protosw_init(void) +diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c +index c957775..6d4593a 100644 +--- a/net/sctp/sm_sideeffect.c ++++ b/net/sctp/sm_sideeffect.c +@@ -447,7 +447,7 @@ static void sctp_generate_sack_event(unsigned long data) + sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_SACK); + } + +-sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES] = { ++sctp_timer_event_t * const sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES] = { + NULL, + sctp_generate_t1_cookie_event, + sctp_generate_t1_init_event, diff --git a/net/sctp/socket.c b/net/sctp/socket.c -index cedd9bf..b1fddeb 100644 +index cedd9bf..d577d71 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -4665,6 +4665,8 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len, @@ -82963,6 +87774,88 @@ index cedd9bf..b1fddeb 100644 if (copy_to_user(to, &temp, addrlen)) return -EFAULT; to += addrlen; +@@ -5653,6 +5655,9 @@ static int sctp_getsockopt_assoc_stats(struct sock *sk, int len, + if (len < sizeof(sctp_assoc_t)) + return -EINVAL; + ++ /* Allow the struct to grow and fill in as much as possible */ ++ len = min_t(size_t, len, sizeof(sas)); ++ + if (copy_from_user(&sas, optval, len)) + return -EFAULT; + +@@ -5686,9 +5691,6 @@ static int sctp_getsockopt_assoc_stats(struct sock *sk, int len, + /* Mark beginning of a new observation period */ + asoc->stats.max_obs_rto = asoc->rto_min; + +- /* Allow the struct to grow and fill in as much as possible */ +- len = min_t(size_t, len, sizeof(sas)); +- + if (put_user(len, optlen)) + return -EFAULT; + +diff --git a/net/sctp/ssnmap.c b/net/sctp/ssnmap.c +index 442ad4e..825ea94 100644 +--- a/net/sctp/ssnmap.c ++++ b/net/sctp/ssnmap.c +@@ -41,8 +41,6 @@ + #include <net/sctp/sctp.h> + #include <net/sctp/sm.h> + +-#define MAX_KMALLOC_SIZE 131072 +- + static struct sctp_ssnmap *sctp_ssnmap_init(struct sctp_ssnmap *map, __u16 in, + __u16 out); + +@@ -65,7 +63,7 @@ struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, + int size; + + size = sctp_ssnmap_size(in, out); +- if (size <= MAX_KMALLOC_SIZE) ++ if (size <= KMALLOC_MAX_SIZE) + retval = kmalloc(size, gfp); + else + retval = (struct sctp_ssnmap *) +@@ -82,7 +80,7 @@ struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out, + return retval; + + fail_map: +- if (size <= MAX_KMALLOC_SIZE) ++ if (size <= KMALLOC_MAX_SIZE) + kfree(retval); + else + free_pages((unsigned long)retval, get_order(size)); +@@ -124,7 +122,7 @@ void sctp_ssnmap_free(struct sctp_ssnmap *map) + int size; + + size = sctp_ssnmap_size(map->in.len, map->out.len); +- if (size <= MAX_KMALLOC_SIZE) ++ if (size <= KMALLOC_MAX_SIZE) + kfree(map); + else + free_pages((unsigned long)map, get_order(size)); +diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c +index bf3c6e8..376d8d0 100644 +--- a/net/sctp/sysctl.c ++++ b/net/sctp/sysctl.c +@@ -307,7 +307,7 @@ static int proc_sctp_do_hmac_alg(ctl_table *ctl, + { + struct net *net = current->nsproxy->net_ns; + char tmp[8]; +- ctl_table tbl; ++ ctl_table_no_const tbl; + int ret; + int changed = 0; + char *none = "none"; +@@ -350,7 +350,7 @@ static int proc_sctp_do_hmac_alg(ctl_table *ctl, + + int sctp_sysctl_net_register(struct net *net) + { +- struct ctl_table *table; ++ ctl_table_no_const *table; + int i; + + table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL); diff --git a/net/socket.c b/net/socket.c index 2ca51c7..45d0b31 100644 --- a/net/socket.c @@ -83225,6 +88118,21 @@ index 2ca51c7..45d0b31 100644 set_fs(KERNEL_DS); if (level == SOL_SOCKET) +diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c +index 507b5e8..049e64a 100644 +--- a/net/sunrpc/clnt.c ++++ b/net/sunrpc/clnt.c +@@ -1272,7 +1272,9 @@ call_start(struct rpc_task *task) + (RPC_IS_ASYNC(task) ? "async" : "sync")); + + /* Increment call count */ +- task->tk_msg.rpc_proc->p_count++; ++ pax_open_kernel(); ++ (*(unsigned int *)&task->tk_msg.rpc_proc->p_count)++; ++ pax_close_kernel(); + clnt->cl_stats->rpccnt++; + task->tk_action = call_reserve; + } diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index fb20f25..e3ba316 100644 --- a/net/sunrpc/sched.c @@ -83241,6 +88149,21 @@ index fb20f25..e3ba316 100644 } #else static inline void rpc_task_set_debuginfo(struct rpc_task *task) +diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c +index 2d34b6b..e2d584d 100644 +--- a/net/sunrpc/svc.c ++++ b/net/sunrpc/svc.c +@@ -1156,7 +1156,9 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) + svc_putnl(resv, RPC_SUCCESS); + + /* Bump per-procedure stats counter */ +- procp->pc_count++; ++ pax_open_kernel(); ++ (*(unsigned int *)&procp->pc_count)++; ++ pax_close_kernel(); + + /* Initialize storage for argp and resp */ + memset(rqstp->rq_argp, 0, procp->pc_argsize); diff --git a/net/sunrpc/xprtrdma/svc_rdma.c b/net/sunrpc/xprtrdma/svc_rdma.c index 8343737..677025e 100644 --- a/net/sunrpc/xprtrdma/svc_rdma.c @@ -83565,6 +88488,19 @@ index 5b5c876..3127bf7 100644 done_path_create(&path, dentry); return err; } +diff --git a/net/unix/sysctl_net_unix.c b/net/unix/sysctl_net_unix.c +index 8800604..0526440 100644 +--- a/net/unix/sysctl_net_unix.c ++++ b/net/unix/sysctl_net_unix.c +@@ -28,7 +28,7 @@ static ctl_table unix_table[] = { + + int __net_init unix_sysctl_register(struct net *net) + { +- struct ctl_table *table; ++ ctl_table_no_const *table; + + table = kmemdup(unix_table, sizeof(unix_table), GFP_KERNEL); + if (table == NULL) diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index c8717c1..08539f5 100644 --- a/net/wireless/wext-core.c @@ -83603,7 +88539,7 @@ index c8717c1..08539f5 100644 iwp->length += essid_compat; diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c -index 07c5857..edc6dc0 100644 +index 07c5857..fde4018 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -317,7 +317,7 @@ static void xfrm_policy_kill(struct xfrm_policy *policy) @@ -83669,7 +88605,32 @@ index 07c5857..edc6dc0 100644 return 0; mtu = dst_mtu(dst->child); -@@ -2896,7 +2896,7 @@ static int xfrm_policy_migrate(struct xfrm_policy *pol, +@@ -2457,8 +2457,11 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) + dst_ops->link_failure = xfrm_link_failure; + if (likely(dst_ops->neigh_lookup == NULL)) + dst_ops->neigh_lookup = xfrm_neigh_lookup; +- if (likely(afinfo->garbage_collect == NULL)) +- afinfo->garbage_collect = xfrm_garbage_collect_deferred; ++ if (likely(afinfo->garbage_collect == NULL)) { ++ pax_open_kernel(); ++ *(void **)&afinfo->garbage_collect = xfrm_garbage_collect_deferred; ++ pax_close_kernel(); ++ } + rcu_assign_pointer(xfrm_policy_afinfo[afinfo->family], afinfo); + } + spin_unlock(&xfrm_policy_afinfo_lock); +@@ -2512,7 +2515,9 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo) + dst_ops->check = NULL; + dst_ops->negative_advice = NULL; + dst_ops->link_failure = NULL; +- afinfo->garbage_collect = NULL; ++ pax_open_kernel(); ++ *(void **)&afinfo->garbage_collect = NULL; ++ pax_close_kernel(); + } + return err; + } +@@ -2896,7 +2901,7 @@ static int xfrm_policy_migrate(struct xfrm_policy *pol, sizeof(pol->xfrm_vec[i].saddr)); pol->xfrm_vec[i].encap_family = mp->new_family; /* flush bundles */ @@ -83679,20 +88640,110 @@ index 07c5857..edc6dc0 100644 } diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c -index 3459692..eefb515 100644 +index 3459692..e7cdb1a 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c -@@ -278,7 +278,9 @@ int xfrm_register_mode(struct xfrm_mode *mode, int family) +@@ -194,11 +194,13 @@ int xfrm_register_type(const struct xfrm_type *type, unsigned short family) + + if (unlikely(afinfo == NULL)) + return -EAFNOSUPPORT; +- typemap = afinfo->type_map; ++ typemap = (const struct xfrm_type **)afinfo->type_map; + +- if (likely(typemap[type->proto] == NULL)) ++ if (likely(typemap[type->proto] == NULL)) { ++ pax_open_kernel(); + typemap[type->proto] = type; +- else ++ pax_close_kernel(); ++ } else + err = -EEXIST; + xfrm_state_unlock_afinfo(afinfo); + return err; +@@ -213,12 +215,15 @@ int xfrm_unregister_type(const struct xfrm_type *type, unsigned short family) + + if (unlikely(afinfo == NULL)) + return -EAFNOSUPPORT; +- typemap = afinfo->type_map; ++ typemap = (const struct xfrm_type **)afinfo->type_map; + + if (unlikely(typemap[type->proto] != type)) + err = -ENOENT; +- else ++ else { ++ pax_open_kernel(); + typemap[type->proto] = NULL; ++ pax_close_kernel(); ++ } + xfrm_state_unlock_afinfo(afinfo); + return err; + } +@@ -227,7 +232,6 @@ EXPORT_SYMBOL(xfrm_unregister_type); + static const struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family) + { + struct xfrm_state_afinfo *afinfo; +- const struct xfrm_type **typemap; + const struct xfrm_type *type; + int modload_attempted = 0; + +@@ -235,9 +239,8 @@ retry: + afinfo = xfrm_state_get_afinfo(family); + if (unlikely(afinfo == NULL)) + return NULL; +- typemap = afinfo->type_map; + +- type = typemap[proto]; ++ type = afinfo->type_map[proto]; + if (unlikely(type && !try_module_get(type->owner))) + type = NULL; + if (!type && !modload_attempted) { +@@ -270,7 +273,7 @@ int xfrm_register_mode(struct xfrm_mode *mode, int family) + return -EAFNOSUPPORT; + + err = -EEXIST; +- modemap = afinfo->mode_map; ++ modemap = (struct xfrm_mode **)afinfo->mode_map; + if (modemap[mode->encap]) + goto out; + +@@ -278,8 +281,10 @@ int xfrm_register_mode(struct xfrm_mode *mode, int family) if (!try_module_get(afinfo->owner)) goto out; - mode->afinfo = afinfo; + pax_open_kernel(); -+ *(void **)&mode->afinfo = afinfo; -+ pax_close_kernel(); ++ *(const void **)&mode->afinfo = afinfo; modemap[mode->encap] = mode; ++ pax_close_kernel(); err = 0; + out: +@@ -302,9 +307,11 @@ int xfrm_unregister_mode(struct xfrm_mode *mode, int family) + return -EAFNOSUPPORT; + + err = -ENOENT; +- modemap = afinfo->mode_map; ++ modemap = (struct xfrm_mode **)afinfo->mode_map; + if (likely(modemap[mode->encap] == mode)) { ++ pax_open_kernel(); + modemap[mode->encap] = NULL; ++ pax_close_kernel(); + module_put(mode->afinfo->owner); + err = 0; + } +diff --git a/net/xfrm/xfrm_sysctl.c b/net/xfrm/xfrm_sysctl.c +index 05a6e3d..6716ec9 100644 +--- a/net/xfrm/xfrm_sysctl.c ++++ b/net/xfrm/xfrm_sysctl.c +@@ -42,7 +42,7 @@ static struct ctl_table xfrm_table[] = { + + int __net_init xfrm_sysctl_init(struct net *net) + { +- struct ctl_table *table; ++ ctl_table_no_const *table; + + __xfrm_sysctl_init(net); + diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 0e801c3..5c8ad3b 100644 --- a/scripts/Makefile.build @@ -84087,11 +89138,28 @@ index 68bb4ef..2f419e1 100644 logoname); write_hex_cnt = 0; for (i = 0; i < logo_clutsize; i++) { +diff --git a/scripts/sortextable.h b/scripts/sortextable.h +index e4fd45b..2eeb5c4 100644 +--- a/scripts/sortextable.h ++++ b/scripts/sortextable.h +@@ -106,9 +106,9 @@ do_func(Elf_Ehdr *ehdr, char const *const fname, table_sort_t custom_sort) + const char *secstrtab; + const char *strtab; + char *extab_image; +- int extab_index = 0; +- int i; +- int idx; ++ unsigned int extab_index = 0; ++ unsigned int i; ++ unsigned int idx; + + shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->e_shoff)); + shstrtab_sec = shdr + r2(&ehdr->e_shstrndx); diff --git a/security/Kconfig b/security/Kconfig -index e9c6ac7..ab9590d 100644 +index e9c6ac7..da94e8b 100644 --- a/security/Kconfig +++ b/security/Kconfig -@@ -4,6 +4,902 @@ +@@ -4,6 +4,920 @@ menu "Security options" @@ -84909,6 +89977,24 @@ index e9c6ac7..ab9590d 100644 + Since this has a negligible performance impact, you should enable + this feature. + ++config PAX_CONSTIFY_PLUGIN ++ bool "Automatically constify eligible structures" ++ default y ++ depends on !UML ++ help ++ By saying Y here the compiler will automatically constify a class ++ of types that contain only function pointers. This reduces the ++ kernel's attack surface and also produces a better memory layout. ++ ++ Note that the implementation requires a gcc with plugin support, ++ i.e., gcc 4.5 or newer. You may need to install the supporting ++ headers explicitly in addition to the normal gcc package. ++ ++ Note that if some code really has to modify constified variables ++ then the source code will have to be patched to allow it. Examples ++ can be found in PaX itself (the no_const attribute) and for some ++ out-of-tree modules at http://www.grsecurity.net/~paxguy1/ . ++ +config PAX_USERCOPY + bool "Harden heap object copies between kernel and userland" + default y if GRKERNSEC_CONFIG_AUTO @@ -84994,7 +90080,7 @@ index e9c6ac7..ab9590d 100644 source security/keys/Kconfig config SECURITY_DMESG_RESTRICT -@@ -103,7 +999,7 @@ config INTEL_TXT +@@ -103,7 +1017,7 @@ config INTEL_TXT config LSM_MMAP_MIN_ADDR int "Low address space for LSM to protect from user allocation" depends on SECURITY && SECURITY_SELINUX @@ -85136,6 +90222,63 @@ index 1c26176..64a1ba2 100644 if (iov != iovstack) kfree(iov); +diff --git a/security/keys/key.c b/security/keys/key.c +index 8fb7c7b..ba3610d 100644 +--- a/security/keys/key.c ++++ b/security/keys/key.c +@@ -284,7 +284,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, + + atomic_set(&key->usage, 1); + init_rwsem(&key->sem); +- lockdep_set_class(&key->sem, &type->lock_class); ++ lockdep_set_class(&key->sem, (struct lock_class_key *)&type->lock_class); + key->type = type; + key->user = user; + key->quotalen = quotalen; +@@ -1032,7 +1032,9 @@ int register_key_type(struct key_type *ktype) + struct key_type *p; + int ret; + +- memset(&ktype->lock_class, 0, sizeof(ktype->lock_class)); ++ pax_open_kernel(); ++ memset((void *)&ktype->lock_class, 0, sizeof(ktype->lock_class)); ++ pax_close_kernel(); + + ret = -EEXIST; + down_write(&key_types_sem); +@@ -1044,7 +1046,7 @@ int register_key_type(struct key_type *ktype) + } + + /* store the type */ +- list_add(&ktype->link, &key_types_list); ++ pax_list_add((struct list_head *)&ktype->link, &key_types_list); + + pr_notice("Key type %s registered\n", ktype->name); + ret = 0; +@@ -1066,7 +1068,7 @@ EXPORT_SYMBOL(register_key_type); + void unregister_key_type(struct key_type *ktype) + { + down_write(&key_types_sem); +- list_del_init(&ktype->link); ++ pax_list_del_init((struct list_head *)&ktype->link); + downgrade_write(&key_types_sem); + key_gc_keytype(ktype); + pr_notice("Key type %s unregistered\n", ktype->name); +@@ -1084,10 +1086,10 @@ void __init key_init(void) + 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); + + /* add the special key types */ +- list_add_tail(&key_type_keyring.link, &key_types_list); +- list_add_tail(&key_type_dead.link, &key_types_list); +- list_add_tail(&key_type_user.link, &key_types_list); +- list_add_tail(&key_type_logon.link, &key_types_list); ++ pax_list_add_tail((struct list_head *)&key_type_keyring.link, &key_types_list); ++ pax_list_add_tail((struct list_head *)&key_type_dead.link, &key_types_list); ++ pax_list_add_tail((struct list_head *)&key_type_user.link, &key_types_list); ++ pax_list_add_tail((struct list_head *)&key_type_logon.link, &key_types_list); + + /* record the root user tracking */ + rb_link_node(&root_key_user.node, diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 4b5c948..2054dc1 100644 --- a/security/keys/keyctl.c @@ -85200,6 +90343,19 @@ index 6ece7f2..ecdb55c 100644 goto error; buflen -= tmp; +diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c +index 58dfe08..c5ec083 100644 +--- a/security/keys/process_keys.c ++++ b/security/keys/process_keys.c +@@ -57,7 +57,7 @@ int install_user_keyrings(void) + + kenter("%p{%u}", user, uid); + +- if (user->uid_keyring) { ++ if (user->uid_keyring && user->session_keyring) { + kleave(" = 0 [exist]"); + return 0; + } diff --git a/security/min_addr.c b/security/min_addr.c index f728728..6457a0c 100644 --- a/security/min_addr.c @@ -85341,6 +90497,56 @@ index 20ef514..4182bed 100644 select SECURITYFS select SECURITY_PATH default n +diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c +index 23414b9..b92b314 100644 +--- a/security/yama/yama_lsm.c ++++ b/security/yama/yama_lsm.c +@@ -367,7 +367,7 @@ int yama_ptrace_traceme(struct task_struct *parent) + } + + #ifndef CONFIG_SECURITY_YAMA_STACKED +-static struct security_operations yama_ops = { ++static struct security_operations yama_ops __read_only = { + .name = "yama", + + .ptrace_access_check = yama_ptrace_access_check, +@@ -378,28 +378,24 @@ static struct security_operations yama_ops = { + #endif + + #ifdef CONFIG_SYSCTL ++static int zero __read_only; ++static int max_scope __read_only = YAMA_SCOPE_NO_ATTACH; ++ + static int yama_dointvec_minmax(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos) + { +- int rc; ++ ctl_table_no_const yama_table; + + if (write && !capable(CAP_SYS_PTRACE)) + return -EPERM; + +- rc = proc_dointvec_minmax(table, write, buffer, lenp, ppos); +- if (rc) +- return rc; +- ++ yama_table = *table; + /* Lock the max value if it ever gets set. */ +- if (write && *(int *)table->data == *(int *)table->extra2) +- table->extra1 = table->extra2; +- +- return rc; ++ if (ptrace_scope == max_scope) ++ yama_table.extra1 = &max_scope; ++ return proc_dointvec_minmax(&yama_table, write, buffer, lenp, ppos); + } + +-static int zero; +-static int max_scope = YAMA_SCOPE_NO_ATTACH; +- + struct ctl_path yama_sysctl_path[] = { + { .procname = "kernel", }, + { .procname = "yama", }, diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c index 4cedc69..e59d8a3 100644 --- a/sound/aoa/codecs/onyx.c @@ -85854,7 +91060,7 @@ index 0000000..50f2f2f +size_overflow_hash.h diff --git a/tools/gcc/Makefile b/tools/gcc/Makefile new file mode 100644 -index 0000000..1d09b7e +index 0000000..6920fb3 --- /dev/null +++ b/tools/gcc/Makefile @@ -0,0 +1,43 @@ @@ -85866,10 +91072,10 @@ index 0000000..1d09b7e + +ifeq ($(PLUGINCC),$(HOSTCC)) +HOSTLIBS := hostlibs -+HOST_EXTRACFLAGS += -I$(GCCPLUGINS_DIR)/include -I$(GCCPLUGINS_DIR)/include/c-family -std=gnu99 -ggdb ++HOST_EXTRACFLAGS += -I$(GCCPLUGINS_DIR)/include -std=gnu99 -ggdb +else +HOSTLIBS := hostcxxlibs -+HOST_EXTRACXXFLAGS += -I$(GCCPLUGINS_DIR)/include -I$(GCCPLUGINS_DIR)/include/c-family -std=gnu++98 -ggdb -Wno-unused-parameter ++HOST_EXTRACXXFLAGS += -I$(GCCPLUGINS_DIR)/include -std=gnu++98 -ggdb -Wno-unused-parameter +endif + +$(HOSTLIBS)-y := constify_plugin.so @@ -86237,10 +91443,10 @@ index 0000000..414fe5e +} diff --git a/tools/gcc/constify_plugin.c b/tools/gcc/constify_plugin.c new file mode 100644 -index 0000000..8bd6f995 +index 0000000..43e86d6 --- /dev/null +++ b/tools/gcc/constify_plugin.c -@@ -0,0 +1,359 @@ +@@ -0,0 +1,512 @@ +/* + * Copyright 2011 by Emese Revfy <re.emese@gmail.com> + * Copyright 2011-2013 by PaX Team <pageexec@freemail.hu> @@ -86275,36 +91481,136 @@ index 0000000..8bd6f995 +#include "rtl.h" +#include "emit-rtl.h" +#include "tree-flow.h" ++#include "target.h" + ++// should come from c-tree.h if only it were installed for gcc 4.5... +#define C_TYPE_FIELDS_READONLY(TYPE) TREE_LANG_FLAG_1(TYPE) + ++// unused type flag in all versions 4.5-4.8 ++#define TYPE_CONSTIFY_VISITED(TYPE) TYPE_LANG_FLAG_4(TYPE) ++ +int plugin_is_GPL_compatible; + +static struct plugin_info const_plugin_info = { -+ .version = "201302112000", ++ .version = "201303070020", + .help = "no-constify\tturn off constification\n", +}; + -+static tree get_field_type(tree field) ++typedef struct { ++ bool has_fptr_field; ++ bool has_writable_field; ++ bool has_do_const_field; ++ bool has_no_const_field; ++} constify_info; ++ ++static const_tree get_field_type(const_tree field) +{ + return strip_array_types(TREE_TYPE(field)); +} + -+static bool walk_struct(tree node, bool all); ++static bool is_fptr(const_tree field) ++{ ++ const_tree ptr = get_field_type(field); ++ ++ if (TREE_CODE(ptr) != POINTER_TYPE) ++ return false; ++ ++ return TREE_CODE(TREE_TYPE(ptr)) == FUNCTION_TYPE; ++} ++ ++/* ++ * determine whether the given structure type meets the requirements for automatic constification, ++ * including the constification attributes on nested structure types ++ */ ++static void constifiable(const_tree node, constify_info *cinfo) ++{ ++ const_tree field; ++ ++ gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE); ++ ++ // e.g., pointer to structure fields while still constructing the structure type ++ if (TYPE_FIELDS(node) == NULL_TREE) ++ return; ++ ++ for (field = TYPE_FIELDS(node); field; field = TREE_CHAIN(field)) { ++ const_tree type = get_field_type(field); ++ enum tree_code code = TREE_CODE(type); ++ ++ if (node == type) ++ continue; ++ ++ if (is_fptr(field)) ++ cinfo->has_fptr_field = true; ++ else if (!TREE_READONLY(field)) ++ cinfo->has_writable_field = true; ++ ++ if (code == RECORD_TYPE || code == UNION_TYPE) { ++ if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) ++ cinfo->has_do_const_field = true; ++ else if (lookup_attribute("no_const", TYPE_ATTRIBUTES(type))) ++ cinfo->has_no_const_field = true; ++ else ++ constifiable(type, cinfo); ++ } ++ } ++} ++ ++static bool constified(const_tree node) ++{ ++ constify_info cinfo = { ++ .has_fptr_field = false, ++ .has_writable_field = false, ++ .has_do_const_field = false, ++ .has_no_const_field = false ++ }; ++ ++ gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE); ++ ++ if (lookup_attribute("no_const", TYPE_ATTRIBUTES(node))) { ++ gcc_assert(!TYPE_READONLY(node)); ++ return false; ++ } ++ ++ if (lookup_attribute("do_const", TYPE_ATTRIBUTES(node))) { ++ gcc_assert(TYPE_READONLY(node)); ++ return true; ++ } ++ ++ constifiable(node, &cinfo); ++ if ((!cinfo.has_fptr_field || cinfo.has_writable_field) && !cinfo.has_do_const_field) ++ return false; ++ ++ return TYPE_READONLY(node); ++} ++ +static void deconstify_tree(tree node); + +static void deconstify_type(tree type) +{ + tree field; + ++ gcc_assert(TREE_CODE(type) == RECORD_TYPE || TREE_CODE(type) == UNION_TYPE); ++ + for (field = TYPE_FIELDS(type); field; field = TREE_CHAIN(field)) { -+ tree fieldtype = get_field_type(field); ++ const_tree fieldtype = get_field_type(field); + -+ if (TREE_CODE(fieldtype) != RECORD_TYPE && TREE_CODE(fieldtype) != UNION_TYPE) ++ // special case handling of simple ptr-to-same-array-type members ++ if (TREE_CODE(TREE_TYPE(field)) == POINTER_TYPE) { ++ const_tree ptrtype = TREE_TYPE(TREE_TYPE(field)); ++ ++ if (TREE_CODE(ptrtype) != RECORD_TYPE && TREE_CODE(ptrtype) != UNION_TYPE) ++ continue; ++ if (TREE_TYPE(TREE_TYPE(field)) == type) ++ continue; ++ if (TYPE_MAIN_VARIANT(ptrtype) == TYPE_MAIN_VARIANT(type)) { ++ TREE_TYPE(field) = copy_node(TREE_TYPE(field)); ++ TREE_TYPE(TREE_TYPE(field)) = type; ++ } + continue; -+ if (!TYPE_READONLY(fieldtype)) ++ } ++ if (TREE_CODE(fieldtype) != RECORD_TYPE && TREE_CODE(fieldtype) != UNION_TYPE) + continue; -+ if (!walk_struct(fieldtype, true)) ++ if (!constified(fieldtype)) + continue; + + deconstify_tree(field); @@ -86312,16 +91618,17 @@ index 0000000..8bd6f995 + } + TYPE_READONLY(type) = 0; + C_TYPE_FIELDS_READONLY(type) = 0; ++ if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) ++ TYPE_ATTRIBUTES(type) = remove_attribute("do_const", TYPE_ATTRIBUTES(type)); +} + +static void deconstify_tree(tree node) +{ + tree old_type, new_type, field; + -+// TREE_READONLY(node) = 0; + old_type = TREE_TYPE(node); + while (TREE_CODE(old_type) == ARRAY_TYPE && TREE_CODE(TREE_TYPE(old_type)) != ARRAY_TYPE) { -+ node = old_type; ++ node = TREE_TYPE(node) = copy_node(old_type); + old_type = TREE_TYPE(old_type); + } + @@ -86341,6 +91648,12 @@ index 0000000..8bd6f995 +static tree handle_no_const_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs) +{ + tree type; ++ constify_info cinfo = { ++ .has_fptr_field = false, ++ .has_writable_field = false, ++ .has_do_const_field = false, ++ .has_no_const_field = false ++ }; + + *no_add_attrs = true; + if (TREE_CODE(*node) == FUNCTION_DECL) { @@ -86348,21 +91661,24 @@ index 0000000..8bd6f995 + return NULL_TREE; + } + ++ if (TREE_CODE(*node) == PARM_DECL) { ++ error("%qE attribute does not apply to function parameters", name); ++ return NULL_TREE; ++ } ++ + if (TREE_CODE(*node) == VAR_DECL) { + error("%qE attribute does not apply to variables", name); + return NULL_TREE; + } + + if (TYPE_P(*node)) { -+ if (TREE_CODE(*node) == RECORD_TYPE || TREE_CODE(*node) == UNION_TYPE) -+ *no_add_attrs = false; -+ else -+ error("%qE attribute applies to struct and union types only", name); -+ return NULL_TREE; ++ *no_add_attrs = false; ++ type = *node; ++ } else { ++ gcc_assert(TREE_CODE(*node) == TYPE_DECL); ++ type = TREE_TYPE(*node); + } + -+ type = TREE_TYPE(*node); -+ + if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE) { + error("%qE attribute applies to struct and union types only", name); + return NULL_TREE; @@ -86373,16 +91689,20 @@ index 0000000..8bd6f995 + return NULL_TREE; + } + -+ if (TREE_CODE(*node) == TYPE_DECL && !TYPE_READONLY(type)) { -+ error("%qE attribute used on type that is not constified", name); ++ if (TYPE_P(*node)) { ++ if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) ++ error("%qE attribute is incompatible with 'do_const'", name); + return NULL_TREE; + } + -+ if (TREE_CODE(*node) == TYPE_DECL) { ++ constifiable(type, &cinfo); ++ if ((cinfo.has_fptr_field && !cinfo.has_writable_field) || lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) { + deconstify_tree(*node); ++ TYPE_CONSTIFY_VISITED(TREE_TYPE(*node)) = 1; + return NULL_TREE; + } + ++ error("%qE attribute used on type that is not constified", name); + return NULL_TREE; +} + @@ -86390,6 +91710,8 @@ index 0000000..8bd6f995 +{ + TYPE_READONLY(type) = 1; + C_TYPE_FIELDS_READONLY(type) = 1; ++ TYPE_CONSTIFY_VISITED(type) = 1; ++// TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("do_const"), NULL_TREE, TYPE_ATTRIBUTES(type)); +} + +static tree handle_do_const_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs) @@ -86405,8 +91727,17 @@ index 0000000..8bd6f995 + return NULL_TREE; + } + ++ if (lookup_attribute(IDENTIFIER_POINTER(name), TYPE_ATTRIBUTES(*node))) { ++ error("%qE attribute is already applied to the type", name); ++ return NULL_TREE; ++ } ++ ++ if (lookup_attribute("no_const", TYPE_ATTRIBUTES(*node))) { ++ error("%qE attribute is incompatible with 'no_const'", name); ++ return NULL_TREE; ++ } ++ + *no_add_attrs = false; -+ constify_type(*node); + return NULL_TREE; +} + @@ -86442,61 +91773,54 @@ index 0000000..8bd6f995 + register_attribute(&do_const_attr); +} + -+static bool is_fptr(tree field) ++static void finish_type(void *event_data, void *data) +{ -+ tree ptr = get_field_type(field); -+ -+ if (TREE_CODE(ptr) != POINTER_TYPE) -+ return false; -+ -+ return TREE_CODE(TREE_TYPE(ptr)) == FUNCTION_TYPE; -+} ++ tree type = (tree)event_data; ++ constify_info cinfo = { ++ .has_fptr_field = false, ++ .has_writable_field = false, ++ .has_do_const_field = false, ++ .has_no_const_field = false ++ }; + -+static bool walk_struct(tree node, bool all) -+{ -+ tree field; ++ if (type == NULL_TREE || type == error_mark_node) ++ return; + -+ if (TYPE_FIELDS(node) == NULL_TREE) -+ return false; ++ if (TYPE_FIELDS(type) == NULL_TREE || TYPE_CONSTIFY_VISITED(type)) ++ return; + -+ if (lookup_attribute("do_const", TYPE_ATTRIBUTES(node))) -+ return true; ++ constifiable(type, &cinfo); + -+ if (lookup_attribute("no_const", TYPE_ATTRIBUTES(node))) { -+ gcc_assert(!TYPE_READONLY(node)); -+ deconstify_type(node); -+ return false; ++ if (TYPE_READONLY(type) && C_TYPE_FIELDS_READONLY(type)) { ++ if (!lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) ++ return; ++ if (cinfo.has_writable_field) ++ return; ++ error("'do_const' attribute used on type that is%sconstified", cinfo.has_fptr_field ? " " : " not "); ++ return; + } + -+ for (field = TYPE_FIELDS(node); field; field = TREE_CHAIN(field)) { -+ tree type = get_field_type(field); -+ enum tree_code code = TREE_CODE(type); -+ -+ if (node == type) -+ return false; -+ if (code == RECORD_TYPE || code == UNION_TYPE) { -+ if (!(walk_struct(type, all))) -+ return false; -+ } else if (!is_fptr(field) && (!all || !TREE_READONLY(field))) -+ return false; ++ if (lookup_attribute("no_const", TYPE_ATTRIBUTES(type))) { ++ if ((cinfo.has_fptr_field && !cinfo.has_writable_field) || cinfo.has_do_const_field) { ++ deconstify_type(type); ++ TYPE_CONSTIFY_VISITED(type) = 1; ++ } else ++ error("'no_const' attribute used on type that is not constified"); ++ return; + } -+ return true; -+} -+ -+static void finish_type(void *event_data, void *data) -+{ -+ tree type = (tree)event_data; + -+ if (type == NULL_TREE || type == error_mark_node) ++ if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) { ++ constify_type(type); + return; ++ } + -+ if (TYPE_READONLY(type)) ++ if (cinfo.has_fptr_field && !cinfo.has_writable_field) { ++ constify_type(type); + return; ++ } + -+ if (walk_struct(type, true)) -+ constify_type(type); -+ else -+ deconstify_type(type); ++ deconstify_type(type); ++ TYPE_CONSTIFY_VISITED(type) = 1; +} + +static unsigned int check_local_variables(void) @@ -86525,24 +91849,19 @@ index 0000000..8bd6f995 + if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE) + continue; + -+ if (!TYPE_READONLY(type)) ++ if (!TYPE_READONLY(type) || !C_TYPE_FIELDS_READONLY(type)) + continue; + -+// if (lookup_attribute("no_const", DECL_ATTRIBUTES(var))) -+// continue; -+ -+ if (lookup_attribute("no_const", TYPE_ATTRIBUTES(type))) ++ if (!TYPE_CONSTIFY_VISITED(type)) + continue; + -+ if (walk_struct(type, false)) { -+ error_at(DECL_SOURCE_LOCATION(var), "constified variable %qE cannot be local", var); -+ ret = 1; -+ } ++ error_at(DECL_SOURCE_LOCATION(var), "constified variable %qE cannot be local", var); ++ ret = 1; + } + return ret; +} + -+struct gimple_opt_pass pass_local_variable = { ++static struct gimple_opt_pass pass_local_variable = { + { + .type = GIMPLE_PASS, + .name = "check_local_variables", @@ -86563,6 +91882,45 @@ index 0000000..8bd6f995 + } +}; + ++static struct { ++ const char *name; ++ const char *asm_op; ++} sections[] = { ++ {".init.rodata", "\t.section\t.init.rodata,\"a\""}, ++ {".ref.rodata", "\t.section\t.ref.rodata,\"a\""}, ++ {".devinit.rodata", "\t.section\t.devinit.rodata,\"a\""}, ++ {".devexit.rodata", "\t.section\t.devexit.rodata,\"a\""}, ++ {".cpuinit.rodata", "\t.section\t.cpuinit.rodata,\"a\""}, ++ {".cpuexit.rodata", "\t.section\t.cpuexit.rodata,\"a\""}, ++ {".meminit.rodata", "\t.section\t.meminit.rodata,\"a\""}, ++ {".memexit.rodata", "\t.section\t.memexit.rodata,\"a\""}, ++ {".data..read_only", "\t.section\t.data..read_only,\"a\""}, ++}; ++ ++static unsigned int (*old_section_type_flags)(tree decl, const char *name, int reloc); ++ ++static unsigned int constify_section_type_flags(tree decl, const char *name, int reloc) ++{ ++ size_t i; ++ ++ for (i = 0; i < ARRAY_SIZE(sections); i++) ++ if (!strcmp(sections[i].name, name)) ++ return 0; ++ return old_section_type_flags(decl, name, reloc); ++} ++ ++static void constify_start_unit(void *gcc_data, void *user_data) ++{ ++// size_t i; ++ ++// for (i = 0; i < ARRAY_SIZE(sections); i++) ++// sections[i].section = get_unnamed_section(0, output_section_asm_op, sections[i].asm_op); ++// sections[i].section = get_section(sections[i].name, 0, NULL); ++ ++ old_section_type_flags = targetm.section_type_flags; ++ targetm.section_type_flags = constify_section_type_flags; ++} ++ +int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) +{ + const char * const plugin_name = plugin_info->base_name; @@ -86595,6 +91953,7 @@ index 0000000..8bd6f995 + if (constify) { + register_callback(plugin_name, PLUGIN_FINISH_TYPE, finish_type, NULL); + register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &local_variable_pass_info); ++ register_callback(plugin_name, PLUGIN_START_UNIT, constify_start_unit, NULL); + } + register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL); + @@ -91395,10 +96754,10 @@ index 0000000..5921fd7 +atyfb_setup_generic_49151 atyfb_setup_generic 3 49151 NULL diff --git a/tools/gcc/size_overflow_plugin.c b/tools/gcc/size_overflow_plugin.c new file mode 100644 -index 0000000..d52f2ee +index 0000000..838ea58 --- /dev/null +++ b/tools/gcc/size_overflow_plugin.c -@@ -0,0 +1,1941 @@ +@@ -0,0 +1,1936 @@ +/* + * Copyright 2011, 2012 by Emese Revfy <re.emese@gmail.com> + * Licensed under the GPL v2, or (at your option) v3 @@ -91429,15 +96788,10 @@ index 0000000..d52f2ee +#include "tree-flow.h" +#include "plugin.h" +#include "gimple.h" -+#include "c-common.h" +#include "diagnostic.h" +#include "cfgloop.h" + -+#if BUILDING_GCC_VERSION >= 4007 -+#include "c-tree.h" -+#else -+#define C_DECL_IMPLICIT(EXP) DECL_LANG_FLAG_2 (EXP) -+#endif ++#define C_DECL_IMPLICIT(EXP) DECL_LANG_FLAG_2(EXP) + +#if BUILDING_GCC_VERSION >= 4008 +#define TODO_dump_func 0 |