summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony G. Basile <blueness@gentoo.org>2013-03-06 07:29:10 -0500
committerAnthony G. Basile <blueness@gentoo.org>2013-03-06 07:29:10 -0500
commit40b9f3d9591cf0d15f06b79fd94b43f062293a0d (patch)
tree4bc3233dfaef55ffcbad1c9fe29f747696caa8de
parentGrsec/PaX: 2.9.1-{2.6.32.60,3.2.39,3.8.2}-201303012255 (diff)
downloadhardened-patchset-40b9f3d9591cf0d15f06b79fd94b43f062293a0d.tar.gz
hardened-patchset-40b9f3d9591cf0d15f06b79fd94b43f062293a0d.tar.bz2
hardened-patchset-40b9f3d9591cf0d15f06b79fd94b43f062293a0d.zip
Correct 3.8.2, add bump from 3.8.120130304
-rw-r--r--3.8.2/0000_README6
-rw-r--r--3.8.2/1001_linux-3.8.2.patch3093
-rw-r--r--3.8.2/4420_grsecurity-2.9.1-3.8.2-201303041742.patch (renamed from 3.8.2/4420_grsecurity-2.9.1-3.8.1-201303012255.patch)704
3 files changed, 3412 insertions, 391 deletions
diff --git a/3.8.2/0000_README b/3.8.2/0000_README
index 517c0e6..4525042 100644
--- a/3.8.2/0000_README
+++ b/3.8.2/0000_README
@@ -2,7 +2,11 @@ README
-----------------------------------------------------------------------------
Individual Patch Descriptions:
-----------------------------------------------------------------------------
-Patch: 4420_grsecurity-2.9.1-3.8.1-201303012255.patch
+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
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/3.8.2/1001_linux-3.8.2.patch b/3.8.2/1001_linux-3.8.2.patch
new file mode 100644
index 0000000..0952288
--- /dev/null
+++ b/3.8.2/1001_linux-3.8.2.patch
@@ -0,0 +1,3093 @@
+diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
+index 6c72381..986614d 100644
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -564,6 +564,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
+@@ -754,6 +756,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#]
+@@ -771,6 +774,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 746c856..20d5318 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 3
+ PATCHLEVEL = 8
+-SUBLEVEL = 1
++SUBLEVEL = 2
+ EXTRAVERSION =
+ NAME = Unicycling Gorilla
+
+diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
+index f8fa411..c205035 100644
+--- a/arch/x86/boot/compressed/eboot.c
++++ b/arch/x86/boot/compressed/eboot.c
+@@ -19,23 +19,28 @@
+
+ static efi_system_table_t *sys_table;
+
++static void efi_char16_printk(efi_char16_t *str)
++{
++ struct efi_simple_text_output_protocol *out;
++
++ out = (struct efi_simple_text_output_protocol *)sys_table->con_out;
++ efi_call_phys2(out->output_string, out, str);
++}
++
+ static void efi_printk(char *str)
+ {
+ char *s8;
+
+ for (s8 = str; *s8; s8++) {
+- struct efi_simple_text_output_protocol *out;
+ efi_char16_t ch[2] = { 0 };
+
+ ch[0] = *s8;
+- out = (struct efi_simple_text_output_protocol *)sys_table->con_out;
+-
+ if (*s8 == '\n') {
+ efi_char16_t nl[2] = { '\r', 0 };
+- efi_call_phys2(out->output_string, out, nl);
++ efi_char16_printk(nl);
+ }
+
+- efi_call_phys2(out->output_string, out, ch);
++ efi_char16_printk(ch);
+ }
+ }
+
+@@ -709,7 +714,12 @@ static efi_status_t handle_ramdisks(efi_loaded_image_t *image,
+ if ((u8 *)p >= (u8 *)filename_16 + sizeof(filename_16))
+ break;
+
+- *p++ = *str++;
++ if (*str == '/') {
++ *p++ = '\\';
++ *str++;
++ } else {
++ *p++ = *str++;
++ }
+ }
+
+ *p = '\0';
+@@ -737,7 +747,9 @@ static efi_status_t handle_ramdisks(efi_loaded_image_t *image,
+ status = efi_call_phys5(fh->open, fh, &h, filename_16,
+ EFI_FILE_MODE_READ, (u64)0);
+ if (status != EFI_SUCCESS) {
+- efi_printk("Failed to open initrd file\n");
++ efi_printk("Failed to open initrd file: ");
++ efi_char16_printk(filename_16);
++ efi_printk("\n");
+ goto close_handles;
+ }
+
+diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
+index b994cc8..cbf5121 100644
+--- a/arch/x86/kernel/apic/apic.c
++++ b/arch/x86/kernel/apic/apic.c
+@@ -131,7 +131,7 @@ static int __init parse_lapic(char *arg)
+ {
+ if (config_enabled(CONFIG_X86_32) && !arg)
+ force_enable_local_apic = 1;
+- else if (!strncmp(arg, "notscdeadline", 13))
++ else if (arg && !strncmp(arg, "notscdeadline", 13))
+ setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER);
+ return 0;
+ }
+diff --git a/arch/x86/kernel/head.c b/arch/x86/kernel/head.c
+index 48d9d4e..992f442 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_reserve(lowmem, 0x100000 - lowmem);
+diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
+index 928bf83..e2cd38f 100644
+--- a/arch/x86/platform/efi/efi.c
++++ b/arch/x86/platform/efi/efi.c
+@@ -85,9 +85,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_RUNTIME_SERVICES, &x86_efi_facility);
++ disable_runtime = true;
+ return 0;
+ }
+ early_param("noefi", setup_noefi);
+@@ -734,7 +735,7 @@ void __init efi_init(void)
+ if (!efi_is_native())
+ pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n");
+ else {
+- if (efi_runtime_init())
++ if (disable_runtime || efi_runtime_init())
+ return;
+ set_bit(EFI_RUNTIME_SERVICES, &x86_efi_facility);
+ }
+diff --git a/block/genhd.c b/block/genhd.c
+index 3993ebf..7dcfdd8 100644
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -25,7 +25,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.
+@@ -422,17 +422,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;
+ }
+@@ -646,7 +647,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;
+
+@@ -664,6 +664,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/block/partition-generic.c b/block/partition-generic.c
+index f1d1451..1cb4dec 100644
+--- a/block/partition-generic.c
++++ b/block/partition-generic.c
+@@ -249,11 +249,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/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
+index 38c5078..f5ae996 100644
+--- a/drivers/acpi/Kconfig
++++ b/drivers/acpi/Kconfig
+@@ -268,7 +268,8 @@ config ACPI_CUSTOM_DSDT
+ default ACPI_CUSTOM_DSDT_FILE != ""
+
+ config ACPI_INITRD_TABLE_OVERRIDE
+- bool "ACPI tables can be passed via uncompressed cpio in initrd"
++ bool "ACPI tables override via initrd"
++ depends on BLK_DEV_INITRD && X86
+ default n
+ help
+ This option provides functionality to override arbitrary ACPI tables
+diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
+index 2fcc67d..df85051 100644
+--- a/drivers/acpi/sleep.c
++++ b/drivers/acpi/sleep.c
+@@ -177,6 +177,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/ahci.c b/drivers/ata/ahci.c
+index 4979127..72e3e12 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -265,6 +265,30 @@ static const struct pci_device_id ahci_pci_tbl[] = {
+ { PCI_VDEVICE(INTEL, 0x9c07), board_ahci }, /* Lynx Point-LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci }, /* Lynx Point-LP RAID */
+ { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci }, /* Lynx Point-LP RAID */
++ { PCI_VDEVICE(INTEL, 0x1f22), board_ahci }, /* Avoton AHCI */
++ { PCI_VDEVICE(INTEL, 0x1f23), board_ahci }, /* Avoton AHCI */
++ { PCI_VDEVICE(INTEL, 0x1f24), board_ahci }, /* Avoton RAID */
++ { PCI_VDEVICE(INTEL, 0x1f25), board_ahci }, /* Avoton RAID */
++ { PCI_VDEVICE(INTEL, 0x1f26), board_ahci }, /* Avoton RAID */
++ { PCI_VDEVICE(INTEL, 0x1f27), board_ahci }, /* Avoton RAID */
++ { PCI_VDEVICE(INTEL, 0x1f2e), board_ahci }, /* Avoton RAID */
++ { PCI_VDEVICE(INTEL, 0x1f2f), board_ahci }, /* Avoton RAID */
++ { PCI_VDEVICE(INTEL, 0x1f32), board_ahci }, /* Avoton AHCI */
++ { PCI_VDEVICE(INTEL, 0x1f33), board_ahci }, /* Avoton AHCI */
++ { PCI_VDEVICE(INTEL, 0x1f34), board_ahci }, /* Avoton RAID */
++ { PCI_VDEVICE(INTEL, 0x1f35), board_ahci }, /* Avoton RAID */
++ { PCI_VDEVICE(INTEL, 0x1f36), board_ahci }, /* Avoton RAID */
++ { PCI_VDEVICE(INTEL, 0x1f37), board_ahci }, /* Avoton RAID */
++ { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci }, /* Avoton RAID */
++ { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci }, /* Avoton RAID */
++ { PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */
++ { PCI_VDEVICE(INTEL, 0x8d04), board_ahci }, /* Wellsburg RAID */
++ { PCI_VDEVICE(INTEL, 0x8d06), board_ahci }, /* Wellsburg RAID */
++ { PCI_VDEVICE(INTEL, 0x8d0e), board_ahci }, /* Wellsburg RAID */
++ { PCI_VDEVICE(INTEL, 0x8d62), board_ahci }, /* Wellsburg AHCI */
++ { PCI_VDEVICE(INTEL, 0x8d64), board_ahci }, /* Wellsburg RAID */
++ { PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */
++ { PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */
+
+ /* JMicron 360/1/3/5/6, match class to avoid IDE function */
+ { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
+diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
+index 174eca6..d2ba439 100644
+--- a/drivers/ata/ata_piix.c
++++ b/drivers/ata/ata_piix.c
+@@ -317,6 +317,23 @@ static const struct pci_device_id piix_pci_tbl[] = {
+ { 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/block/nbd.c b/drivers/block/nbd.c
+index 043ddcc..eb591fb 100644
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -595,12 +595,20 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
+ struct request sreq;
+
+ dev_info(disk_to_dev(nbd->disk), "NBD_DISCONNECT\n");
++ if (!nbd->sock)
++ return -EINVAL;
+
++ mutex_unlock(&nbd->tx_lock);
++ fsync_bdev(bdev);
++ mutex_lock(&nbd->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 (!nbd->sock)
+ return -EINVAL;
++
+ nbd_send_req(nbd, &sreq);
+ return 0;
+ }
+@@ -614,6 +622,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
+ nbd_clear_que(nbd);
+ BUG_ON(!list_empty(&nbd->queue_head));
+ BUG_ON(!list_empty(&nbd->waiting_queue));
++ kill_bdev(bdev);
+ if (file)
+ fput(file);
+ return 0;
+@@ -702,6 +711,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
+ nbd->file = NULL;
+ nbd_clear_que(nbd);
+ dev_warn(disk_to_dev(nbd->disk), "queue cleared\n");
++ kill_bdev(bdev);
+ queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, nbd->disk->queue);
+ if (file)
+ fput(file);
+diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
+index 5ac841f..de1f319 100644
+--- a/drivers/block/xen-blkback/blkback.c
++++ b/drivers/block/xen-blkback/blkback.c
+@@ -46,6 +46,7 @@
+ #include <xen/xen.h>
+ #include <asm/xen/hypervisor.h>
+ #include <asm/xen/hypercall.h>
++#include <xen/balloon.h>
+ #include "common.h"
+
+ /*
+@@ -239,6 +240,7 @@ static void free_persistent_gnts(struct rb_root *root, unsigned int num)
+ ret = gnttab_unmap_refs(unmap, NULL, pages,
+ segs_to_unmap);
+ BUG_ON(ret);
++ free_xenballooned_pages(segs_to_unmap, pages);
+ segs_to_unmap = 0;
+ }
+
+@@ -527,8 +529,8 @@ static int xen_blkbk_map(struct blkif_request *req,
+ GFP_KERNEL);
+ if (!persistent_gnt)
+ return -ENOMEM;
+- persistent_gnt->page = alloc_page(GFP_KERNEL);
+- if (!persistent_gnt->page) {
++ if (alloc_xenballooned_pages(1, &persistent_gnt->page,
++ false)) {
+ kfree(persistent_gnt);
+ return -ENOMEM;
+ }
+@@ -879,7 +881,6 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
+ goto fail_response;
+ }
+
+- preq.dev = req->u.rw.handle;
+ preq.sector_number = req->u.rw.sector_number;
+ preq.nr_sects = 0;
+
+diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
+index 6398072..5e237f6 100644
+--- a/drivers/block/xen-blkback/xenbus.c
++++ b/drivers/block/xen-blkback/xenbus.c
+@@ -367,6 +367,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;
+@@ -502,6 +503,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("");
+@@ -521,10 +523,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;
+ }
+
+@@ -542,36 +544,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/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
+index 11043c1..c3dae2e 100644
+--- a/drivers/block/xen-blkfront.c
++++ b/drivers/block/xen-blkfront.c
+@@ -791,7 +791,7 @@ static void blkif_restart_queue(struct work_struct *work)
+ static void blkif_free(struct blkfront_info *info, int suspend)
+ {
+ struct llist_node *all_gnts;
+- struct grant *persistent_gnt;
++ struct grant *persistent_gnt, *tmp;
+ struct llist_node *n;
+
+ /* Prevent new requests being issued until we fix things up. */
+@@ -805,10 +805,17 @@ static void blkif_free(struct blkfront_info *info, int suspend)
+ /* Remove all persistent grants */
+ if (info->persistent_gnts_c) {
+ all_gnts = llist_del_all(&info->persistent_gnts);
+- llist_for_each_entry_safe(persistent_gnt, n, all_gnts, node) {
++ persistent_gnt = llist_entry(all_gnts, typeof(*(persistent_gnt)), node);
++ while (persistent_gnt) {
+ gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL);
+ __free_page(pfn_to_page(persistent_gnt->pfn));
+- kfree(persistent_gnt);
++ tmp = persistent_gnt;
++ n = persistent_gnt->node.next;
++ if (n)
++ persistent_gnt = llist_entry(n, typeof(*(persistent_gnt)), node);
++ else
++ persistent_gnt = NULL;
++ kfree(tmp);
+ }
+ info->persistent_gnts_c = 0;
+ }
+diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
+index 3873d53..af3e8aa 100644
+--- a/drivers/firewire/core-device.c
++++ b/drivers/firewire/core-device.c
+@@ -1020,6 +1020,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/firmware/efivars.c b/drivers/firmware/efivars.c
+index f5596db..bcb201c 100644
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -79,6 +79,7 @@
+ #include <linux/device.h>
+ #include <linux/slab.h>
+ #include <linux/pstore.h>
++#include <linux/ctype.h>
+
+ #include <linux/fs.h>
+ #include <linux/ramfs.h>
+@@ -900,6 +901,48 @@ static struct inode *efivarfs_get_inode(struct super_block *sb,
+ return inode;
+ }
+
++/*
++ * Return true if 'str' is a valid efivarfs filename of the form,
++ *
++ * VariableName-12345678-1234-1234-1234-1234567891bc
++ */
++static bool efivarfs_valid_name(const char *str, int len)
++{
++ static const char dashes[GUID_LEN] = {
++ [8] = 1, [13] = 1, [18] = 1, [23] = 1
++ };
++ const char *s = str + len - GUID_LEN;
++ int i;
++
++ /*
++ * We need a GUID, plus at least one letter for the variable name,
++ * plus the '-' separator
++ */
++ if (len < GUID_LEN + 2)
++ return false;
++
++ /* GUID should be right after the first '-' */
++ if (s - 1 != strchr(str, '-'))
++ return false;
++
++ /*
++ * Validate that 's' is of the correct format, e.g.
++ *
++ * 12345678-1234-1234-1234-123456789abc
++ */
++ for (i = 0; i < GUID_LEN; i++) {
++ if (dashes[i]) {
++ if (*s++ != '-')
++ return false;
++ } else {
++ if (!isxdigit(*s++))
++ return false;
++ }
++ }
++
++ return true;
++}
++
+ static void efivarfs_hex_to_guid(const char *str, efi_guid_t *guid)
+ {
+ guid->b[0] = hex_to_bin(str[6]) << 4 | hex_to_bin(str[7]);
+@@ -928,11 +971,7 @@ static int efivarfs_create(struct inode *dir, struct dentry *dentry,
+ struct efivar_entry *var;
+ int namelen, i = 0, err = 0;
+
+- /*
+- * We need a GUID, plus at least one letter for the variable name,
+- * plus the '-' separator
+- */
+- if (dentry->d_name.len < GUID_LEN + 2)
++ if (!efivarfs_valid_name(dentry->d_name.name, dentry->d_name.len))
+ return -EINVAL;
+
+ inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0);
+@@ -1004,6 +1043,84 @@ static int efivarfs_unlink(struct inode *dir, struct dentry *dentry)
+ return -EINVAL;
+ };
+
++/*
++ * Compare two efivarfs file names.
++ *
++ * An efivarfs filename is composed of two parts,
++ *
++ * 1. A case-sensitive variable name
++ * 2. A case-insensitive GUID
++ *
++ * So we need to perform a case-sensitive match on part 1 and a
++ * case-insensitive match on part 2.
++ */
++static int efivarfs_d_compare(const struct dentry *parent, const struct inode *pinode,
++ const struct dentry *dentry, const struct inode *inode,
++ unsigned int len, const char *str,
++ const struct qstr *name)
++{
++ int guid = len - GUID_LEN;
++
++ if (name->len != len)
++ return 1;
++
++ /* Case-sensitive compare for the variable name */
++ if (memcmp(str, name->name, guid))
++ return 1;
++
++ /* Case-insensitive compare for the GUID */
++ return strncasecmp(name->name + guid, str + guid, GUID_LEN);
++}
++
++static int efivarfs_d_hash(const struct dentry *dentry,
++ const struct inode *inode, struct qstr *qstr)
++{
++ unsigned long hash = init_name_hash();
++ const unsigned char *s = qstr->name;
++ unsigned int len = qstr->len;
++
++ if (!efivarfs_valid_name(s, len))
++ return -EINVAL;
++
++ while (len-- > GUID_LEN)
++ hash = partial_name_hash(*s++, hash);
++
++ /* GUID is case-insensitive. */
++ while (len--)
++ hash = partial_name_hash(tolower(*s++), hash);
++
++ qstr->hash = end_name_hash(hash);
++ return 0;
++}
++
++/*
++ * Retaining negative dentries for an in-memory filesystem just wastes
++ * memory and lookup time: arrange for them to be deleted immediately.
++ */
++static int efivarfs_delete_dentry(const struct dentry *dentry)
++{
++ return 1;
++}
++
++static struct dentry_operations efivarfs_d_ops = {
++ .d_compare = efivarfs_d_compare,
++ .d_hash = efivarfs_d_hash,
++ .d_delete = efivarfs_delete_dentry,
++};
++
++static struct dentry *efivarfs_alloc_dentry(struct dentry *parent, char *name)
++{
++ struct qstr q;
++
++ q.name = name;
++ q.len = strlen(name);
++
++ if (efivarfs_d_hash(NULL, NULL, &q))
++ return NULL;
++
++ return d_alloc(parent, &q);
++}
++
+ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
+ {
+ struct inode *inode = NULL;
+@@ -1019,6 +1136,7 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
+ sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+ sb->s_magic = EFIVARFS_MAGIC;
+ sb->s_op = &efivarfs_ops;
++ sb->s_d_op = &efivarfs_d_ops;
+ sb->s_time_gran = 1;
+
+ inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0);
+@@ -1059,7 +1177,7 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent)
+ if (!inode)
+ goto fail_name;
+
+- dentry = d_alloc_name(root, name);
++ dentry = efivarfs_alloc_dentry(root, name);
+ if (!dentry)
+ goto fail_inode;
+
+@@ -1109,8 +1227,20 @@ static struct file_system_type efivarfs_type = {
+ .kill_sb = efivarfs_kill_sb,
+ };
+
++/*
++ * Handle negative dentry.
++ */
++static struct dentry *efivarfs_lookup(struct inode *dir, struct dentry *dentry,
++ unsigned int flags)
++{
++ if (dentry->d_name.len > NAME_MAX)
++ return ERR_PTR(-ENAMETOOLONG);
++ d_add(dentry, NULL);
++ return NULL;
++}
++
+ static const struct inode_operations efivarfs_dir_inode_operations = {
+- .lookup = simple_lookup,
++ .lookup = efivarfs_lookup,
+ .unlink = efivarfs_unlink,
+ .create = efivarfs_create,
+ };
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index eb2ee11..ceb3040 100644
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -1697,6 +1697,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
+@@ -2070,6 +2071,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 34e2547..266e2ae 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -554,6 +554,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
+@@ -709,6 +712,7 @@
+
+ #define USB_VENDOR_ID_SONY 0x054c
+ #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b
++#define USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE 0x0374
+ #define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306
+ #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
+ #define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f
+diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
+index 7f33ebf..126d6ae 100644
+--- a/drivers/hid/hid-sony.c
++++ b/drivers/hid/hid-sony.c
+@@ -43,9 +43,19 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ {
+ struct sony_sc *sc = hid_get_drvdata(hdev);
+
+- if ((sc->quirks & VAIO_RDESC_CONSTANT) &&
+- *rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) {
+- hid_info(hdev, "Fixing up Sony Vaio VGX report descriptor\n");
++ /*
++ * Some Sony RF receivers wrongly declare the mouse pointer as a
++ * a constant non-data variable.
++ */
++ if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 &&
++ /* usage page: generic desktop controls */
++ /* rdesc[0] == 0x05 && rdesc[1] == 0x01 && */
++ /* usage: mouse */
++ rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
++ /* input (usage page for x,y axes): constant, variable, relative */
++ rdesc[54] == 0x81 && rdesc[55] == 0x07) {
++ hid_info(hdev, "Fixing up Sony RF Receiver report descriptor\n");
++ /* input: data, variable, relative */
+ rdesc[55] = 0x06;
+ }
+
+@@ -217,6 +227,8 @@ static const struct hid_device_id sony_devices[] = {
+ .driver_data = SIXAXIS_CONTROLLER_BT },
+ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
+ .driver_data = VAIO_RDESC_CONSTANT },
++ { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE),
++ .driver_data = VAIO_RDESC_CONSTANT },
+ { }
+ };
+ MODULE_DEVICE_TABLE(hid, sony_devices);
+diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
+index d5088ce..7ccf328 100644
+--- a/drivers/infiniband/ulp/srp/ib_srp.c
++++ b/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -700,23 +700,24 @@ static int srp_reconnect_target(struct srp_target_port *target)
+ struct Scsi_Host *shost = target->scsi_host;
+ int i, ret;
+
+- if (target->state != SRP_TARGET_LIVE)
+- return -EAGAIN;
+-
+ scsi_target_block(&shost->shost_gendev);
+
+ srp_disconnect_target(target);
+ /*
+- * Now get a new local CM ID so that we avoid confusing the
+- * target in case things are really fouled up.
++ * Now get a new local CM ID so that we avoid confusing the target in
++ * case things are really fouled up. Doing so also ensures that all CM
++ * callbacks will have finished before a new QP is allocated.
+ */
+ ret = srp_new_cm_id(target);
+- if (ret)
+- goto unblock;
+-
+- ret = srp_create_target_ib(target);
+- if (ret)
+- goto unblock;
++ /*
++ * Whether or not creating a new CM ID succeeded, create a new
++ * QP. This guarantees that all completion callback function
++ * invocations have finished before request resetting starts.
++ */
++ if (ret == 0)
++ ret = srp_create_target_ib(target);
++ else
++ srp_create_target_ib(target);
+
+ for (i = 0; i < SRP_CMD_SQ_SIZE; ++i) {
+ struct srp_request *req = &target->req_ring[i];
+@@ -728,11 +729,12 @@ static int srp_reconnect_target(struct srp_target_port *target)
+ for (i = 0; i < SRP_SQ_SIZE; ++i)
+ list_add(&target->tx_ring[i]->list, &target->free_tx);
+
+- ret = srp_connect_target(target);
++ if (ret == 0)
++ ret = srp_connect_target(target);
+
+-unblock:
+ scsi_target_unblock(&shost->shost_gendev, ret == 0 ? SDEV_RUNNING :
+ SDEV_TRANSPORT_OFFLINE);
++ target->transport_offline = !!ret;
+
+ if (ret)
+ goto err;
+@@ -1352,6 +1354,12 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)
+ unsigned long flags;
+ int len;
+
++ if (unlikely(target->transport_offline)) {
++ scmnd->result = DID_NO_CONNECT << 16;
++ scmnd->scsi_done(scmnd);
++ return 0;
++ }
++
+ spin_lock_irqsave(&target->lock, flags);
+ iu = __srp_get_tx_iu(target, SRP_IU_CMD);
+ if (!iu)
+@@ -1695,6 +1703,9 @@ static int srp_send_tsk_mgmt(struct srp_target_port *target,
+ struct srp_iu *iu;
+ struct srp_tsk_mgmt *tsk_mgmt;
+
++ if (!target->connected || target->qp_in_error)
++ return -1;
++
+ init_completion(&target->tsk_mgmt_done);
+
+ spin_lock_irq(&target->lock);
+@@ -1736,7 +1747,7 @@ static int srp_abort(struct scsi_cmnd *scmnd)
+
+ shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n");
+
+- if (!req || target->qp_in_error || !srp_claim_req(target, req, scmnd))
++ if (!req || !srp_claim_req(target, req, scmnd))
+ return FAILED;
+ srp_send_tsk_mgmt(target, req->index, scmnd->device->lun,
+ SRP_TSK_ABORT_TASK);
+@@ -1754,8 +1765,6 @@ static int srp_reset_device(struct scsi_cmnd *scmnd)
+
+ shost_printk(KERN_ERR, target->scsi_host, "SRP reset_device called\n");
+
+- if (target->qp_in_error)
+- return FAILED;
+ if (srp_send_tsk_mgmt(target, SRP_TAG_NO_REQ, scmnd->device->lun,
+ SRP_TSK_LUN_RESET))
+ return FAILED;
+@@ -1972,7 +1981,6 @@ static int srp_add_target(struct srp_host *host, struct srp_target_port *target)
+ spin_unlock(&host->target_lock);
+
+ target->state = SRP_TARGET_LIVE;
+- target->connected = false;
+
+ scsi_scan_target(&target->scsi_host->shost_gendev,
+ 0, target->scsi_id, SCAN_WILD_CARD, 0);
+diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h
+index de2d0b3..66fbedd 100644
+--- a/drivers/infiniband/ulp/srp/ib_srp.h
++++ b/drivers/infiniband/ulp/srp/ib_srp.h
+@@ -140,6 +140,7 @@ struct srp_target_port {
+ unsigned int cmd_sg_cnt;
+ unsigned int indirect_size;
+ bool allow_ext_sg;
++ bool transport_offline;
+
+ /* Everything above this point is used in the hot path of
+ * command processing. Try to keep them packed into cachelines.
+diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
+index faf10ba..b6ecddb 100644
+--- a/drivers/iommu/amd_iommu_init.c
++++ b/drivers/iommu/amd_iommu_init.c
+@@ -1876,11 +1876,6 @@ static int amd_iommu_init_dma(void)
+ struct amd_iommu *iommu;
+ int ret;
+
+- init_device_table_dma();
+-
+- for_each_iommu(iommu)
+- iommu_flush_all_caches(iommu);
+-
+ if (iommu_pass_through)
+ ret = amd_iommu_init_passthrough();
+ else
+@@ -1889,6 +1884,11 @@ static int amd_iommu_init_dma(void)
+ if (ret)
+ return ret;
+
++ init_device_table_dma();
++
++ for_each_iommu(iommu)
++ iommu_flush_all_caches(iommu);
++
+ amd_iommu_init_api();
+
+ amd_iommu_init_notifier();
+diff --git a/drivers/media/pci/cx18/cx18-alsa-main.c b/drivers/media/pci/cx18/cx18-alsa-main.c
+index 8e971ff..b2c8c34 100644
+--- a/drivers/media/pci/cx18/cx18-alsa-main.c
++++ b/drivers/media/pci/cx18/cx18-alsa-main.c
+@@ -197,7 +197,7 @@ err_exit:
+ return ret;
+ }
+
+-static int __init cx18_alsa_load(struct cx18 *cx)
++static int cx18_alsa_load(struct cx18 *cx)
+ {
+ struct v4l2_device *v4l2_dev = &cx->v4l2_dev;
+ struct cx18_stream *s;
+diff --git a/drivers/media/pci/cx18/cx18-alsa-pcm.h b/drivers/media/pci/cx18/cx18-alsa-pcm.h
+index d26e51f..e2b2c5b 100644
+--- a/drivers/media/pci/cx18/cx18-alsa-pcm.h
++++ b/drivers/media/pci/cx18/cx18-alsa-pcm.h
+@@ -20,7 +20,7 @@
+ * 02111-1307 USA
+ */
+
+-int __init snd_cx18_pcm_create(struct snd_cx18_card *cxsc);
++int snd_cx18_pcm_create(struct snd_cx18_card *cxsc);
+
+ /* Used by cx18-mailbox to announce the PCM data to the module */
+ void cx18_alsa_announce_pcm_data(struct snd_cx18_card *card, u8 *pcm_data,
+diff --git a/drivers/media/pci/ivtv/ivtv-alsa-main.c b/drivers/media/pci/ivtv/ivtv-alsa-main.c
+index 4a221c6..e970cfa 100644
+--- a/drivers/media/pci/ivtv/ivtv-alsa-main.c
++++ b/drivers/media/pci/ivtv/ivtv-alsa-main.c
+@@ -205,7 +205,7 @@ err_exit:
+ return ret;
+ }
+
+-static int __init ivtv_alsa_load(struct ivtv *itv)
++static int ivtv_alsa_load(struct ivtv *itv)
+ {
+ struct v4l2_device *v4l2_dev = &itv->v4l2_dev;
+ struct ivtv_stream *s;
+diff --git a/drivers/media/pci/ivtv/ivtv-alsa-pcm.h b/drivers/media/pci/ivtv/ivtv-alsa-pcm.h
+index 23dfe0d..186814e 100644
+--- a/drivers/media/pci/ivtv/ivtv-alsa-pcm.h
++++ b/drivers/media/pci/ivtv/ivtv-alsa-pcm.h
+@@ -20,4 +20,4 @@
+ * 02111-1307 USA
+ */
+
+-int __init snd_ivtv_pcm_create(struct snd_ivtv_card *itvsc);
++int snd_ivtv_pcm_create(struct snd_ivtv_card *itvsc);
+diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
+index 35cc526..8e9a668 100644
+--- a/drivers/media/platform/omap/omap_vout.c
++++ b/drivers/media/platform/omap/omap_vout.c
+@@ -205,19 +205,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(&current->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(&current->mm->mmap_sem);
+ } else {
+ /* otherwise, use get_user_pages() for general userland pages */
+ int res, nr_pages = 1;
+ struct page *pages;
+- down_read(&current->mm->mmap_sem);
+
+ res = get_user_pages(current, current->mm, virtp, nr_pages, 1,
+ 0, &pages, NULL);
+diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
+index 601d1ac1..d593bc6 100644
+--- a/drivers/media/rc/rc-main.c
++++ b/drivers/media/rc/rc-main.c
+@@ -789,8 +789,10 @@ static ssize_t show_protocols(struct device *device,
+ } else if (dev->raw) {
+ enabled = dev->raw->enabled_protocols;
+ allowed = ir_raw_get_allowed_protocols();
+- } else
++ } else {
++ mutex_unlock(&dev->lock);
+ return -ENODEV;
++ }
+
+ IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
+ (long long)allowed,
+diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c
+index 513969f..98a7f5e 100644
+--- a/drivers/media/v4l2-core/v4l2-device.c
++++ b/drivers/media/v4l2-core/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, NULL);
+- 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/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
+index 806e34c..0568273 100644
+--- a/drivers/net/wireless/b43/main.c
++++ b/drivers/net/wireless/b43/main.c
+@@ -4214,7 +4214,6 @@ redo:
+ mutex_unlock(&wl->mutex);
+ cancel_delayed_work_sync(&dev->periodic_work);
+ cancel_work_sync(&wl->tx_work);
+- cancel_work_sync(&wl->firmware_load);
+ mutex_lock(&wl->mutex);
+ dev = wl->current_dev;
+ if (!dev || b43_status(dev) < B43_STAT_STARTED) {
+@@ -5434,6 +5433,7 @@ static void b43_bcma_remove(struct bcma_device *core)
+ /* We must cancel any work here before unregistering from ieee80211,
+ * as the ieee80211 unreg will destroy the workqueue. */
+ cancel_work_sync(&wldev->restart_work);
++ cancel_work_sync(&wl->firmware_load);
+
+ B43_WARN_ON(!wl);
+ if (!wldev->fw.ucode.data)
+@@ -5510,6 +5510,7 @@ static void b43_ssb_remove(struct ssb_device *sdev)
+ /* We must cancel any work here before unregistering from ieee80211,
+ * as the ieee80211 unreg will destroy the workqueue. */
+ cancel_work_sync(&wldev->restart_work);
++ cancel_work_sync(&wl->firmware_load);
+
+ B43_WARN_ON(!wl);
+ if (!wldev->fw.ucode.data)
+diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c
+index 20e2a7d..056222e 100644
+--- a/drivers/power/ab8500_btemp.c
++++ b/drivers/power/ab8500_btemp.c
+@@ -1123,7 +1123,7 @@ static void __exit ab8500_btemp_exit(void)
+ platform_driver_unregister(&ab8500_btemp_driver);
+ }
+
+-subsys_initcall_sync(ab8500_btemp_init);
++device_initcall(ab8500_btemp_init);
+ module_exit(ab8500_btemp_exit);
+
+ MODULE_LICENSE("GPL v2");
+diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c
+index 2970891..eb7b4a6 100644
+--- a/drivers/power/abx500_chargalg.c
++++ b/drivers/power/abx500_chargalg.c
+@@ -1698,7 +1698,7 @@ static ssize_t abx500_chargalg_sysfs_charger(struct kobject *kobj,
+ static struct attribute abx500_chargalg_en_charger = \
+ {
+ .name = "chargalg",
+- .mode = S_IWUGO,
++ .mode = S_IWUSR,
+ };
+
+ static struct attribute *abx500_chargalg_chg[] = {
+diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
+index 36b34ef..7087d0d 100644
+--- a/drivers/power/bq27x00_battery.c
++++ b/drivers/power/bq27x00_battery.c
+@@ -448,7 +448,6 @@ static void bq27x00_update(struct bq27x00_device_info *di)
+ cache.temperature = bq27x00_battery_read_temperature(di);
+ if (!is_bq27425)
+ cache.cycle_count = bq27x00_battery_read_cyct(di);
+- cache.cycle_count = bq27x00_battery_read_cyct(di);
+ cache.power_avg =
+ bq27x00_battery_read_pwr_avg(di, BQ27x00_POWER_AVG);
+
+@@ -696,7 +695,6 @@ static int bq27x00_powersupply_init(struct bq27x00_device_info *di)
+ int ret;
+
+ di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
+- di->chip = BQ27425;
+ if (di->chip == BQ27425) {
+ di->bat.properties = bq27425_battery_props;
+ di->bat.num_properties = ARRAY_SIZE(bq27425_battery_props);
+diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
+index 8f14c42..6894b3e 100644
+--- a/drivers/staging/comedi/comedi_fops.c
++++ b/drivers/staging/comedi/comedi_fops.c
+@@ -1779,7 +1779,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
+@@ -1789,7 +1789,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);
+@@ -1831,7 +1831,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;
+ }
+@@ -1942,7 +1942,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/target/target_core_device.c b/drivers/target/target_core_device.c
+index f2aa754..96f4981 100644
+--- a/drivers/target/target_core_device.c
++++ b/drivers/target/target_core_device.c
+@@ -1182,24 +1182,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");
+@@ -1210,7 +1204,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 c57bbbc..04c775c 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_internal.h b/drivers/target/target_core_internal.h
+index 93e9c1f..396e1eb 100644
+--- a/drivers/target/target_core_internal.h
++++ b/drivers/target/target_core_internal.h
+@@ -45,7 +45,7 @@ struct se_lun *core_dev_add_lun(struct se_portal_group *, struct se_device *, u3
+ int core_dev_del_lun(struct se_portal_group *, u32);
+ struct se_lun *core_get_lun_from_tpg(struct se_portal_group *, u32);
+ struct se_lun_acl *core_dev_init_initiator_node_lun_acl(struct se_portal_group *,
+- u32, char *, int *);
++ struct se_node_acl *, u32, int *);
+ int core_dev_add_initiator_node_lun_acl(struct se_portal_group *,
+ struct se_lun_acl *, u32, u32);
+ int core_dev_del_initiator_node_lun_acl(struct se_portal_group *,
+diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c
+index 5192ac0..9169d6a 100644
+--- a/drivers/target/target_core_tpg.c
++++ b/drivers/target/target_core_tpg.c
+@@ -111,16 +111,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/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
+index 4999563..1dae91d 100644
+--- a/drivers/usb/dwc3/core.h
++++ b/drivers/usb/dwc3/core.h
+@@ -405,7 +405,6 @@ struct dwc3_event_buffer {
+ * @number: endpoint number (1 - 15)
+ * @type: set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK
+ * @resource_index: Resource transfer index
+- * @current_uf: Current uf received through last event parameter
+ * @interval: the intervall on which the ISOC transfer is started
+ * @name: a human readable name e.g. ep1out-bulk
+ * @direction: true for TX, false for RX
+@@ -439,7 +438,6 @@ struct dwc3_ep {
+ u8 number;
+ u8 type;
+ u8 resource_index;
+- u16 current_uf;
+ u32 interval;
+
+ char name[20];
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 2fdd767..09835b6 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -754,21 +754,18 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
+ struct dwc3 *dwc = dep->dwc;
+ struct dwc3_trb *trb;
+
+- unsigned int cur_slot;
+-
+ dev_vdbg(dwc->dev, "%s: req %p dma %08llx length %d%s%s\n",
+ dep->name, req, (unsigned long long) dma,
+ length, last ? " last" : "",
+ chain ? " chain" : "");
+
+- trb = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
+- cur_slot = dep->free_slot;
+- dep->free_slot++;
+-
+ /* Skip the LINK-TRB on ISOC */
+- if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
++ if (((dep->free_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
+ usb_endpoint_xfer_isoc(dep->endpoint.desc))
+- return;
++ dep->free_slot++;
++
++ trb = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
++ dep->free_slot++;
+
+ if (!req->trb) {
+ dwc3_gadget_move_request_queued(req);
+@@ -1091,7 +1088,10 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
+ * notion of current microframe.
+ */
+ if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
+- dwc3_stop_active_transfer(dwc, dep->number);
++ if (list_empty(&dep->req_queued)) {
++ dwc3_stop_active_transfer(dwc, dep->number);
++ dep->flags = DWC3_EP_ENABLED;
++ }
+ return 0;
+ }
+
+@@ -1117,16 +1117,6 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
+ dep->name);
+ }
+
+- /*
+- * 3. Missed ISOC Handling. We need to start isoc transfer on the saved
+- * uframe number.
+- */
+- if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
+- (dep->flags & DWC3_EP_MISSED_ISOC)) {
+- __dwc3_gadget_start_isoc(dwc, dep, dep->current_uf);
+- dep->flags &= ~DWC3_EP_MISSED_ISOC;
+- }
+-
+ return 0;
+ }
+
+@@ -1689,14 +1679,29 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
+ if (trb_status == DWC3_TRBSTS_MISSED_ISOC) {
+ dev_dbg(dwc->dev, "incomplete IN transfer %s\n",
+ dep->name);
+- dep->current_uf = event->parameters &
+- ~(dep->interval - 1);
++ /*
++ * If missed isoc occurred and there is
++ * no request queued then issue END
++ * TRANSFER, so that core generates
++ * next xfernotready and we will issue
++ * a fresh START TRANSFER.
++ * If there are still queued request
++ * then wait, do not issue either END
++ * or UPDATE TRANSFER, just attach next
++ * request in request_list during
++ * giveback.If any future queued request
++ * is successfully transferred then we
++ * will issue UPDATE TRANSFER for all
++ * request in the request_list.
++ */
+ dep->flags |= DWC3_EP_MISSED_ISOC;
+ } else {
+ dev_err(dwc->dev, "incomplete IN transfer %s\n",
+ dep->name);
+ status = -ECONNRESET;
+ }
++ } else {
++ dep->flags &= ~DWC3_EP_MISSED_ISOC;
+ }
+ } else {
+ if (count && (event->status & DEPEVT_STATUS_SHORT))
+@@ -1723,6 +1728,23 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
+ break;
+ } while (1);
+
++ if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
++ list_empty(&dep->req_queued)) {
++ if (list_empty(&dep->request_list)) {
++ /*
++ * If there is no entry in request list then do
++ * not issue END TRANSFER now. Just set PENDING
++ * flag, so that END TRANSFER is issued when an
++ * entry is added into request list.
++ */
++ dep->flags = DWC3_EP_PENDING_REQUEST;
++ } else {
++ dwc3_stop_active_transfer(dwc, dep->number);
++ dep->flags = DWC3_EP_ENABLED;
++ }
++ return 1;
++ }
++
+ if ((event->status & DEPEVT_STATUS_IOC) &&
+ (trb->ctrl & DWC3_TRB_CTRL_IOC))
+ return 0;
+@@ -2157,6 +2179,26 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)
+ break;
+ }
+
++ /* Enable USB2 LPM Capability */
++
++ if ((dwc->revision > DWC3_REVISION_194A)
++ && (speed != DWC3_DCFG_SUPERSPEED)) {
++ reg = dwc3_readl(dwc->regs, DWC3_DCFG);
++ reg |= DWC3_DCFG_LPM_CAP;
++ dwc3_writel(dwc->regs, DWC3_DCFG, reg);
++
++ reg = dwc3_readl(dwc->regs, DWC3_DCTL);
++ reg &= ~(DWC3_DCTL_HIRD_THRES_MASK | DWC3_DCTL_L1_HIBER_EN);
++
++ /*
++ * TODO: This should be configurable. For now using
++ * maximum allowed HIRD threshold value of 0b1100
++ */
++ reg |= DWC3_DCTL_HIRD_THRES(12);
++
++ dwc3_writel(dwc->regs, DWC3_DCTL, reg);
++ }
++
+ /* Recent versions support automatic phy suspend and don't need this */
+ if (dwc->revision < DWC3_REVISION_194A) {
+ /* Suspend unneeded PHY */
+@@ -2463,20 +2505,8 @@ int dwc3_gadget_init(struct dwc3 *dwc)
+ DWC3_DEVTEN_DISCONNEVTEN);
+ dwc3_writel(dwc->regs, DWC3_DEVTEN, reg);
+
+- /* Enable USB2 LPM and automatic phy suspend only on recent versions */
++ /* automatic phy suspend only on recent versions */
+ if (dwc->revision >= DWC3_REVISION_194A) {
+- reg = dwc3_readl(dwc->regs, DWC3_DCFG);
+- reg |= DWC3_DCFG_LPM_CAP;
+- dwc3_writel(dwc->regs, DWC3_DCFG, reg);
+-
+- reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+- reg &= ~(DWC3_DCTL_HIRD_THRES_MASK | DWC3_DCTL_L1_HIBER_EN);
+-
+- /* TODO: This should be configurable */
+- reg |= DWC3_DCTL_HIRD_THRES(28);
+-
+- dwc3_writel(dwc->regs, DWC3_DCTL, reg);
+-
+ dwc3_gadget_usb2_phy_suspend(dwc, false);
+ dwc3_gadget_usb3_phy_suspend(dwc, false);
+ }
+diff --git a/fs/direct-io.c b/fs/direct-io.c
+index cf5b44b..f853263 100644
+--- a/fs/direct-io.c
++++ b/fs/direct-io.c
+@@ -261,9 +261,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/ext4/balloc.c b/fs/ext4/balloc.c
+index cf18217..2f2e0da 100644
+--- a/fs/ext4/balloc.c
++++ b/fs/ext4/balloc.c
+@@ -358,7 +358,7 @@ void ext4_validate_block_bitmap(struct super_block *sb,
+ }
+
+ /**
+- * ext4_read_block_bitmap()
++ * ext4_read_block_bitmap_nowait()
+ * @sb: super block
+ * @block_group: given block group
+ *
+@@ -457,6 +457,8 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
+ struct buffer_head *bh;
+
+ bh = ext4_read_block_bitmap_nowait(sb, block_group);
++ if (!bh)
++ return NULL;
+ if (ext4_wait_block_bitmap(sb, block_group, bh)) {
+ put_bh(bh);
+ return NULL;
+@@ -482,11 +484,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 5ae1674..d42a8c4 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -725,6 +725,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);
+@@ -752,12 +753,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;
+ }
+@@ -768,13 +772,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 (ext4_ext_check_block(inode, eh, i, bh))
++ ret = ext4_ext_check_block(inode, eh, i, bh);
++ if (ret < 0)
+ goto err;
+ }
+
+@@ -796,7 +802,7 @@ err:
+ ext4_ext_drop_refs(path);
+ if (alloc)
+ kfree(path);
+- return ERR_PTR(-EIO);
++ return ERR_PTR(ret);
+ }
+
+ /*
+@@ -951,7 +957,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);
+@@ -1024,7 +1030,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);
+@@ -1136,11 +1142,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);
+diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
+index 20862f9..8d83d1e 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/inline.c b/fs/ext4/inline.c
+index 387c47c..93a3408 100644
+--- a/fs/ext4/inline.c
++++ b/fs/ext4/inline.c
+@@ -1188,7 +1188,7 @@ static int ext4_convert_inline_data_nolock(handle_t *handle,
+
+ data_bh = sb_getblk(inode->i_sb, map.m_pblk);
+ if (!data_bh) {
+- error = -EIO;
++ error = -ENOMEM;
+ goto out_restore;
+ }
+
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index cbfe13b..39f1fa7 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -714,7 +714,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) {
+@@ -2977,9 +2977,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;
+ }
+
+@@ -3660,11 +3660,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 1bf6fe7..061727a 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -4136,7 +4136,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);
+@@ -4160,12 +4160,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 fe7c63f..44734f1 100644
+--- a/fs/ext4/mmp.c
++++ b/fs/ext4/mmp.c
+@@ -80,6 +80,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 0016fbc..b42d04f 100644
+--- a/fs/ext4/page-io.c
++++ b/fs/ext4/page-io.c
+@@ -103,14 +103,13 @@ static int ext4_end_io(ext4_io_end_t *io)
+ "(inode %lu, offset %llu, size %zd, error %d)",
+ 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_unwritten))
+ wake_up_all(ext4_ioend_wq(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 d99387b..02824dc 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -334,7 +334,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);
+@@ -411,7 +411,7 @@ static int set_flexbg_block_bitmap(struct super_block *sb, handle_t *handle,
+
+ bh = sb_getblk(sb, flex_gd->groups[group].block_bitmap);
+ if (!bh)
+- return -EIO;
++ return -ENOMEM;
+
+ err = ext4_journal_get_write_access(handle, bh);
+ if (err)
+@@ -501,7 +501,7 @@ static int setup_new_flex_group_blocks(struct super_block *sb,
+
+ gdb = sb_getblk(sb, block);
+ if (!gdb) {
+- err = -EIO;
++ err = -ENOMEM;
+ goto out;
+ }
+
+@@ -1065,7 +1065,7 @@ static void update_backups(struct super_block *sb, int blk_off, char *data,
+
+ bh = sb_getblk(sb, backup_block);
+ if (!bh) {
+- err = -EIO;
++ err = -ENOMEM;
+ break;
+ }
+ ext4_debug("update metadata backup %llu(+%llu)\n",
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 3d4fb81..0465f36 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -4008,7 +4008,7 @@ no_journal:
+ !(sb->s_flags & MS_RDONLY)) {
+ err = ext4_enable_quotas(sb);
+ if (err)
+- goto failed_mount7;
++ goto failed_mount8;
+ }
+ #endif /* CONFIG_QUOTA */
+
+@@ -4035,6 +4035,10 @@ cantfind_ext4:
+ ext4_msg(sb, KERN_ERR, "VFS: Can't find ext4 filesystem");
+ goto failed_mount;
+
++#ifdef CONFIG_QUOTA
++failed_mount8:
++ kobject_del(&sbi->s_kobj);
++#endif
+ failed_mount7:
+ ext4_unregister_li_request(sb);
+ failed_mount6:
+@@ -5005,9 +5009,9 @@ static int ext4_enable_quotas(struct super_block *sb)
+ DQUOT_USAGE_ENABLED);
+ if (err) {
+ ext4_warning(sb,
+- "Failed to enable quota (type=%d) "
+- "tracking. Please run e2fsck to fix.",
+- type);
++ "Failed to enable quota tracking "
++ "(type=%d, err=%d). Please run "
++ "e2fsck to fix.", type, err);
+ return err;
+ }
+ }
+diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+index 3a91ebc..b93846b 100644
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -549,7 +549,7 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
+ error = ext4_handle_dirty_xattr_block(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));
+ }
+@@ -832,7 +832,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,
+@@ -887,16 +888,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);
+@@ -928,7 +930,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/fuse/dir.c b/fs/fuse/dir.c
+index b7c09f9..315e1f8 100644
+--- a/fs/fuse/dir.c
++++ b/fs/fuse/dir.c
+@@ -682,7 +682,14 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
+
+ spin_lock(&fc->lock);
+ fi->attr_version = ++fc->attr_version;
+- drop_nlink(inode);
++ /*
++ * If i_nlink == 0 then unlink doesn't make sense, yet this can
++ * happen if userspace filesystem is careless. It would be
++ * difficult to enforce correct nlink usage so just ignore this
++ * condition here
++ */
++ if (inode->i_nlink > 0)
++ drop_nlink(inode);
+ spin_unlock(&fc->lock);
+ fuse_invalidate_attr(inode);
+ fuse_invalidate_attr(dir);
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index ac8ed96c..a8309c6 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -1060,6 +1060,8 @@ free_client(struct nfs4_client *clp)
+ }
+ free_svc_cred(&clp->cl_cred);
+ kfree(clp->cl_name.data);
++ idr_remove_all(&clp->cl_stateids);
++ idr_destroy(&clp->cl_stateids);
+ kfree(clp);
+ }
+
+diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
+index 6577432..340bd02 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/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 0ba9ea1..2e3ea30 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/pstore/platform.c b/fs/pstore/platform.c
+index 5ea2e77..86d1038 100644
+--- a/fs/pstore/platform.c
++++ b/fs/pstore/platform.c
+@@ -96,6 +96,27 @@ static const char *get_reason_str(enum kmsg_dump_reason reason)
+ }
+ }
+
++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
+@@ -114,10 +135,12 @@ static void pstore_dump(struct kmsg_dumper *dumper,
+
+ why = get_reason_str(reason);
+
+- 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++;
+@@ -143,9 +166,9 @@ static void pstore_dump(struct kmsg_dumper *dumper,
+ total += hsize + len;
+ 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 769701c..ba32da3 100644
+--- a/fs/ubifs/orphan.c
++++ b/fs/ubifs/orphan.c
+@@ -126,13 +126,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) {
++ if (o->cmt) {
++ o->del = 1;
+ o->dnext = c->orph_dnext;
+ c->orph_dnext = o;
+ spin_unlock(&c->orphan_lock);
+@@ -172,7 +173,9 @@ int ubifs_orphan_start_commit(struct ubifs_info *c)
+ last = &c->orph_cnext;
+ list_for_each_entry(orphan, &c->orph_new, new_list) {
+ ubifs_assert(orphan->new);
++ ubifs_assert(!orphan->cmt);
+ orphan->new = 0;
++ orphan->cmt = 1;
+ *last = orphan;
+ last = &orphan->cnext;
+ }
+@@ -299,7 +302,9 @@ static int write_orph_node(struct ubifs_info *c, int atomic)
+ cnext = c->orph_cnext;
+ for (i = 0; i < cnt; i++) {
+ orphan = cnext;
++ ubifs_assert(orphan->cmt);
+ orph->inos[i] = cpu_to_le64(orphan->inum);
++ orphan->cmt = 0;
+ cnext = orphan->cnext;
+ orphan->cnext = NULL;
+ }
+@@ -378,6 +383,7 @@ static int consolidate(struct ubifs_info *c)
+ list_for_each_entry(orphan, &c->orph_list, list) {
+ if (orphan->new)
+ continue;
++ orphan->cmt = 1;
+ *last = orphan;
+ last = &orphan->cnext;
+ cnt += 1;
+@@ -442,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;
+@@ -531,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 d133c27..b2babce 100644
+--- a/fs/ubifs/ubifs.h
++++ b/fs/ubifs/ubifs.h
+@@ -904,6 +904,8 @@ struct ubifs_budget_req {
+ * @dnext: next orphan to delete
+ * @inum: inode number
+ * @new: %1 => added since the last commit, otherwise %0
++ * @cmt: %1 => commit pending, otherwise %0
++ * @del: %1 => delete pending, otherwise %0
+ */
+ struct ubifs_orphan {
+ struct rb_node rb;
+@@ -912,7 +914,9 @@ struct ubifs_orphan {
+ struct ubifs_orphan *cnext;
+ struct ubifs_orphan *dnext;
+ ino_t inum;
+- int new;
++ unsigned new:1;
++ unsigned cmt:1;
++ unsigned del:1;
+ };
+
+ /**
+diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
+index cdb2d33..572a858 100644
+--- a/fs/xfs/xfs_bmap.c
++++ b/fs/xfs/xfs_bmap.c
+@@ -147,7 +147,10 @@ xfs_bmap_local_to_extents(
+ xfs_fsblock_t *firstblock, /* first block allocated in xaction */
+ xfs_extlen_t total, /* total blocks needed by transaction */
+ int *logflagsp, /* inode logging flags */
+- int whichfork); /* data or attr fork */
++ int whichfork, /* data or attr fork */
++ void (*init_fn)(struct xfs_buf *bp,
++ struct xfs_inode *ip,
++ struct xfs_ifork *ifp));
+
+ /*
+ * Search the extents list for the inode, for the extent containing bno.
+@@ -357,7 +360,42 @@ xfs_bmap_add_attrfork_extents(
+ }
+
+ /*
+- * Called from xfs_bmap_add_attrfork to handle local format files.
++ * Block initialisation functions for local to extent format conversion.
++ * As these get more complex, they will be moved to the relevant files,
++ * but for now they are too simple to worry about.
++ */
++STATIC void
++xfs_bmap_local_to_extents_init_fn(
++ struct xfs_buf *bp,
++ struct xfs_inode *ip,
++ struct xfs_ifork *ifp)
++{
++ bp->b_ops = &xfs_bmbt_buf_ops;
++ memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);
++}
++
++STATIC void
++xfs_symlink_local_to_remote(
++ struct xfs_buf *bp,
++ struct xfs_inode *ip,
++ struct xfs_ifork *ifp)
++{
++ /* remote symlink blocks are not verifiable until CRCs come along */
++ bp->b_ops = NULL;
++ memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);
++}
++
++/*
++ * Called from xfs_bmap_add_attrfork to handle local format files. Each
++ * different data fork content type needs a different callout to do the
++ * conversion. Some are basic and only require special block initialisation
++ * callouts for the data formating, others (directories) are so specialised they
++ * handle everything themselves.
++ *
++ * XXX (dgc): investigate whether directory conversion can use the generic
++ * formatting callout. It should be possible - it's just a very complex
++ * formatter. it would also require passing the transaction through to the init
++ * function.
+ */
+ STATIC int /* error */
+ xfs_bmap_add_attrfork_local(
+@@ -368,25 +406,29 @@ xfs_bmap_add_attrfork_local(
+ int *flags) /* inode logging flags */
+ {
+ xfs_da_args_t dargs; /* args for dir/attr code */
+- int error; /* error return value */
+- xfs_mount_t *mp; /* mount structure pointer */
+
+ if (ip->i_df.if_bytes <= XFS_IFORK_DSIZE(ip))
+ return 0;
++
+ if (S_ISDIR(ip->i_d.di_mode)) {
+- mp = ip->i_mount;
+ memset(&dargs, 0, sizeof(dargs));
+ dargs.dp = ip;
+ dargs.firstblock = firstblock;
+ dargs.flist = flist;
+- dargs.total = mp->m_dirblkfsbs;
++ dargs.total = ip->i_mount->m_dirblkfsbs;
+ dargs.whichfork = XFS_DATA_FORK;
+ dargs.trans = tp;
+- error = xfs_dir2_sf_to_block(&dargs);
+- } else
+- error = xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags,
+- XFS_DATA_FORK);
+- return error;
++ return xfs_dir2_sf_to_block(&dargs);
++ }
++
++ if (S_ISLNK(ip->i_d.di_mode))
++ return xfs_bmap_local_to_extents(tp, ip, firstblock, 1,
++ flags, XFS_DATA_FORK,
++ xfs_symlink_local_to_remote);
++
++ return xfs_bmap_local_to_extents(tp, ip, firstblock, 1, flags,
++ XFS_DATA_FORK,
++ xfs_bmap_local_to_extents_init_fn);
+ }
+
+ /*
+@@ -3221,7 +3263,10 @@ xfs_bmap_local_to_extents(
+ xfs_fsblock_t *firstblock, /* first block allocated in xaction */
+ xfs_extlen_t total, /* total blocks needed by transaction */
+ int *logflagsp, /* inode logging flags */
+- int whichfork) /* data or attr fork */
++ int whichfork,
++ void (*init_fn)(struct xfs_buf *bp,
++ struct xfs_inode *ip,
++ struct xfs_ifork *ifp))
+ {
+ int error; /* error return value */
+ int flags; /* logging flags returned */
+@@ -3241,12 +3286,12 @@ xfs_bmap_local_to_extents(
+ xfs_buf_t *bp; /* buffer for extent block */
+ xfs_bmbt_rec_host_t *ep;/* extent record pointer */
+
++ ASSERT((ifp->if_flags &
++ (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE);
+ memset(&args, 0, sizeof(args));
+ args.tp = tp;
+ args.mp = ip->i_mount;
+ args.firstblock = *firstblock;
+- ASSERT((ifp->if_flags &
+- (XFS_IFINLINE|XFS_IFEXTENTS|XFS_IFEXTIREC)) == XFS_IFINLINE);
+ /*
+ * Allocate a block. We know we need only one, since the
+ * file currently fits in an inode.
+@@ -3262,17 +3307,20 @@ xfs_bmap_local_to_extents(
+ args.mod = args.minleft = args.alignment = args.wasdel =
+ args.isfl = args.minalignslop = 0;
+ args.minlen = args.maxlen = args.prod = 1;
+- if ((error = xfs_alloc_vextent(&args)))
++ error = xfs_alloc_vextent(&args);
++ if (error)
+ goto done;
+- /*
+- * Can't fail, the space was reserved.
+- */
++
++ /* Can't fail, the space was reserved. */
+ ASSERT(args.fsbno != NULLFSBLOCK);
+ ASSERT(args.len == 1);
+ *firstblock = args.fsbno;
+ bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0);
+- bp->b_ops = &xfs_bmbt_buf_ops;
+- memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);
++
++ /* initialise the block and copy the data */
++ init_fn(bp, ip, ifp);
++
++ /* account for the change in fork size and log everything */
+ xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
+ xfs_bmap_forkoff_reset(args.mp, ip, whichfork);
+ xfs_idata_realloc(ip, -ifp->if_bytes, whichfork);
+@@ -4919,8 +4967,32 @@ xfs_bmapi_write(
+ XFS_STATS_INC(xs_blk_mapw);
+
+ if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL) {
++ /*
++ * XXX (dgc): This assumes we are only called for inodes that
++ * contain content neutral data in local format. Anything that
++ * contains caller-specific data in local format that needs
++ * transformation to move to a block format needs to do the
++ * conversion to extent format itself.
++ *
++ * Directory data forks and attribute forks handle this
++ * themselves, but with the addition of metadata verifiers every
++ * data fork in local format now contains caller specific data
++ * and as such conversion through this function is likely to be
++ * broken.
++ *
++ * The only likely user of this branch is for remote symlinks,
++ * but we cannot overwrite the data fork contents of the symlink
++ * (EEXIST occurs higher up the stack) and so it will never go
++ * from local format to extent format here. Hence I don't think
++ * this branch is ever executed intentionally and we should
++ * consider removing it and asserting that xfs_bmapi_write()
++ * cannot be called directly on local format forks. i.e. callers
++ * are completely responsible for local to extent format
++ * conversion, not xfs_bmapi_write().
++ */
+ error = xfs_bmap_local_to_extents(tp, ip, firstblock, total,
+- &bma.logflags, whichfork);
++ &bma.logflags, whichfork,
++ xfs_bmap_local_to_extents_init_fn);
+ if (error)
+ goto error0;
+ }
+diff --git a/include/linux/llist.h b/include/linux/llist.h
+index d0ab98f..a5199f6 100644
+--- a/include/linux/llist.h
++++ b/include/linux/llist.h
+@@ -125,31 +125,6 @@ static inline void init_llist_head(struct llist_head *list)
+ (pos) = llist_entry((pos)->member.next, typeof(*(pos)), member))
+
+ /**
+- * llist_for_each_entry_safe - iterate safely against remove over some entries
+- * of lock-less list of given type.
+- * @pos: the type * to use as a loop cursor.
+- * @n: another type * to use as a temporary storage.
+- * @node: the fist entry of deleted list entries.
+- * @member: the name of the llist_node with the struct.
+- *
+- * In general, some entries of the lock-less list can be traversed
+- * safely only after being removed from list, so start with an entry
+- * instead of list head. This variant allows removal of entries
+- * as we iterate.
+- *
+- * If being used on entries deleted from lock-less list directly, the
+- * traverse order is from the newest to the oldest added entry. If
+- * you want to traverse from the oldest to the newest, you must
+- * reverse the order by yourself before traversing.
+- */
+-#define llist_for_each_entry_safe(pos, n, node, member) \
+- for ((pos) = llist_entry((node), typeof(*(pos)), member), \
+- (n) = (pos)->member.next; \
+- &(pos)->member != NULL; \
+- (pos) = llist_entry(n, typeof(*(pos)), member), \
+- (n) = (&(pos)->member != NULL) ? (pos)->member.next : NULL)
+-
+-/**
+ * llist_empty - tests whether a lock-less list is empty
+ * @head: the list to test
+ *
+diff --git a/include/linux/pstore.h b/include/linux/pstore.h
+index 1788909..75d0176 100644
+--- a/include/linux/pstore.h
++++ b/include/linux/pstore.h
+@@ -68,12 +68,18 @@ struct pstore_info {
+
+ #ifdef CONFIG_PSTORE
+ extern int pstore_register(struct pstore_info *);
++extern bool pstore_cannot_block_path(enum kmsg_dump_reason reason);
+ #else
+ static inline int
+ pstore_register(struct pstore_info *psi)
+ {
+ return -ENODEV;
+ }
++static inline bool
++pstore_cannot_block_path(enum kmsg_dump_reason reason)
++{
++ return false;
++}
+ #endif
+
+ #endif /*_LINUX_PSTORE_H*/
+diff --git a/include/linux/quota.h b/include/linux/quota.h
+index 58fdef12..d133711 100644
+--- a/include/linux/quota.h
++++ b/include/linux/quota.h
+@@ -405,6 +405,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 /* _QUOTA_ */
+diff --git a/kernel/cgroup.c b/kernel/cgroup.c
+index 4855892..1e23664 100644
+--- a/kernel/cgroup.c
++++ b/kernel/cgroup.c
+@@ -426,12 +426,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 7bb63ee..5bb9bf1 100644
+--- a/kernel/cpuset.c
++++ b/kernel/cpuset.c
+@@ -2511,8 +2511,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/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 5a63844..0ddf3a0 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/trace/ftrace.c b/kernel/trace/ftrace.c
+index 41473b4..43defd1 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -3970,37 +3970,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[];
+
+@@ -4032,9 +4046,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 033ad5b..3a3a98f 100644
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -138,6 +138,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 */
+@@ -910,7 +911,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;
+ }
+@@ -920,9 +922,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).
+@@ -2168,7 +2188,6 @@ __acquires(&gcwq->lock)
+ struct global_cwq *gcwq = pool->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
+@@ -2208,6 +2227,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);
+
+@@ -2240,7 +2260,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.
+@@ -2252,7 +2272,8 @@ __acquires(&gcwq->lock)
+ if (unlikely(in_atomic() || lockdep_depth(current) > 0)) {
+ 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), f);
++ current->comm, preempt_count(), task_pid_nr(current),
++ worker->current_func);
+ debug_show_held_locks(current);
+ dump_stack();
+ }
+@@ -2266,6 +2287,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);
+ }
+diff --git a/lib/idr.c b/lib/idr.c
+index 6482390..ca5aa00 100644
+--- a/lib/idr.c
++++ b/lib/idr.c
+@@ -625,7 +625,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;
+diff --git a/mm/mmap.c b/mm/mmap.c
+index d1e4124..8832b87 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -2169,9 +2169,28 @@ int expand_downwards(struct vm_area_struct *vma,
+ return error;
+ }
+
++/*
++ * Note how expand_stack() refuses to expand the stack all the way to
++ * abut the next virtual mapping, *unless* that mapping itself is also
++ * a stack mapping. We want to leave room for a guard page, after all
++ * (the guard page itself is not added here, that is done by the
++ * actual page faulting logic)
++ *
++ * This matches the behavior of the guard page logic (see mm/memory.c:
++ * check_stack_guard_page()), which only allows the guard page to be
++ * removed under these circumstances.
++ */
+ #ifdef CONFIG_STACK_GROWSUP
+ int expand_stack(struct vm_area_struct *vma, unsigned long address)
+ {
++ struct vm_area_struct *next;
++
++ address &= PAGE_MASK;
++ next = vma->vm_next;
++ if (next && next->vm_start == address + PAGE_SIZE) {
++ if (!(next->vm_flags & VM_GROWSUP))
++ return -ENOMEM;
++ }
+ return expand_upwards(vma, address);
+ }
+
+@@ -2194,6 +2213,14 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr)
+ #else
+ int expand_stack(struct vm_area_struct *vma, unsigned long address)
+ {
++ struct vm_area_struct *prev;
++
++ address &= PAGE_MASK;
++ prev = vma->vm_prev;
++ if (prev && prev->vm_end == address) {
++ if (!(prev->vm_flags & VM_GROWSDOWN))
++ return -ENOMEM;
++ }
+ return expand_downwards(vma, address);
+ }
+
+diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
+index dbf12ac..2d34b6b 100644
+--- a/net/sunrpc/svc.c
++++ b/net/sunrpc/svc.c
+@@ -515,15 +515,6 @@ EXPORT_SYMBOL_GPL(svc_create_pooled);
+
+ void svc_shutdown_net(struct svc_serv *serv, struct net *net)
+ {
+- /*
+- * The set of xprts (contained in the sv_tempsocks and
+- * sv_permsocks lists) is now constant, since it is modified
+- * only by accepting new sockets (done by service threads in
+- * svc_recv) or aging old ones (done by sv_temptimer), or
+- * configuration changes (excluded by whatever locking the
+- * caller is using--nfsd_mutex in the case of nfsd). So it's
+- * safe to traverse those lists and shut everything down:
+- */
+ svc_close_net(serv, net);
+
+ if (serv->sv_shutdown)
+diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
+index b8e47fa..ca71056 100644
+--- a/net/sunrpc/svc_xprt.c
++++ b/net/sunrpc/svc_xprt.c
+@@ -856,7 +856,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");
+
+@@ -877,25 +876,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);
+ }
+@@ -959,21 +948,24 @@ void svc_close_xprt(struct svc_xprt *xprt)
+ }
+ EXPORT_SYMBOL_GPL(svc_close_xprt);
+
+-static void svc_close_list(struct svc_serv *serv, struct list_head *xprt_list, struct net *net)
++static int svc_close_list(struct svc_serv *serv, struct list_head *xprt_list, struct net *net)
+ {
+ struct svc_xprt *xprt;
++ int ret = 0;
+
+ spin_lock(&serv->sv_lock);
+ list_for_each_entry(xprt, xprt_list, xpt_list) {
+ if (xprt->xpt_net != net)
+ continue;
++ ret++;
+ set_bit(XPT_CLOSE, &xprt->xpt_flags);
+- set_bit(XPT_BUSY, &xprt->xpt_flags);
++ svc_xprt_enqueue(xprt);
+ }
+ spin_unlock(&serv->sv_lock);
++ return ret;
+ }
+
+-static void svc_clear_pools(struct svc_serv *serv, struct net *net)
++static struct svc_xprt *svc_dequeue_net(struct svc_serv *serv, struct net *net)
+ {
+ struct svc_pool *pool;
+ struct svc_xprt *xprt;
+@@ -988,42 +980,46 @@ static void svc_clear_pools(struct svc_serv *serv, struct net *net)
+ if (xprt->xpt_net != net)
+ continue;
+ list_del_init(&xprt->xpt_ready);
++ spin_unlock_bh(&pool->sp_lock);
++ return xprt;
+ }
+ spin_unlock_bh(&pool->sp_lock);
+ }
++ return NULL;
+ }
+
+-static void svc_clear_list(struct svc_serv *serv, struct list_head *xprt_list, struct net *net)
++static void svc_clean_up_xprts(struct svc_serv *serv, struct net *net)
+ {
+ struct svc_xprt *xprt;
+- struct svc_xprt *tmp;
+- LIST_HEAD(victims);
+-
+- spin_lock(&serv->sv_lock);
+- list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) {
+- if (xprt->xpt_net != net)
+- continue;
+- list_move(&xprt->xpt_list, &victims);
+- }
+- spin_unlock(&serv->sv_lock);
+
+- list_for_each_entry_safe(xprt, tmp, &victims, xpt_list)
++ while ((xprt = svc_dequeue_net(serv, net))) {
++ set_bit(XPT_CLOSE, &xprt->xpt_flags);
+ svc_delete_xprt(xprt);
++ }
+ }
+
++/*
++ * Server threads may still be running (especially in the case where the
++ * service is still running in other network namespaces).
++ *
++ * So we shut down sockets the same way we would on a running server, by
++ * setting XPT_CLOSE, enqueuing, and letting a thread pick it up to do
++ * the close. In the case there are no such other threads,
++ * threads running, svc_clean_up_xprts() does a simple version of a
++ * server's main event loop, and in the case where there are other
++ * threads, we may need to wait a little while and then check again to
++ * see if they're done.
++ */
+ void svc_close_net(struct svc_serv *serv, struct net *net)
+ {
+- svc_close_list(serv, &serv->sv_tempsocks, net);
+- svc_close_list(serv, &serv->sv_permsocks, net);
++ int delay = 0;
+
+- svc_clear_pools(serv, net);
+- /*
+- * At this point the sp_sockets lists will stay empty, since
+- * svc_xprt_enqueue will not add new entries without taking the
+- * sp_lock and checking XPT_BUSY.
+- */
+- svc_clear_list(serv, &serv->sv_tempsocks, net);
+- svc_clear_list(serv, &serv->sv_permsocks, net);
++ while (svc_close_list(serv, &serv->sv_permsocks, net) +
++ svc_close_list(serv, &serv->sv_tempsocks, net)) {
++
++ svc_clean_up_xprts(serv, net);
++ msleep(delay++);
++ }
+ }
+
+ /*
+diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
+index cdd100d..9febe55 100644
+--- a/sound/pci/bt87x.c
++++ b/sound/pci/bt87x.c
+@@ -836,6 +836,8 @@ static struct {
+ {0x7063, 0x2000}, /* pcHDTV HD-2000 TV */
+ };
+
++static struct pci_driver driver;
++
+ /* return the id of the card, or a negative value if it's blacklisted */
+ static int snd_bt87x_detect_card(struct pci_dev *pci)
+ {
+@@ -962,11 +964,24 @@ static DEFINE_PCI_DEVICE_TABLE(snd_bt87x_default_ids) = {
+ { }
+ };
+
+-static struct pci_driver bt87x_driver = {
++static struct pci_driver driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = snd_bt87x_ids,
+ .probe = snd_bt87x_probe,
+ .remove = snd_bt87x_remove,
+ };
+
+-module_pci_driver(bt87x_driver);
++static int __init alsa_card_bt87x_init(void)
++{
++ if (load_all)
++ driver.id_table = snd_bt87x_default_ids;
++ return pci_register_driver(&driver);
++}
++
++static void __exit alsa_card_bt87x_exit(void)
++{
++ pci_unregister_driver(&driver);
++}
++
++module_init(alsa_card_bt87x_init)
++module_exit(alsa_card_bt87x_exit)
+diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
+index a7c296a..e6b0166 100644
+--- a/sound/pci/emu10k1/emu10k1_main.c
++++ b/sound/pci/emu10k1/emu10k1_main.c
+@@ -862,6 +862,12 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
+ filename, emu->firmware->size);
+ }
+
++ err = snd_emu1010_load_firmware(emu);
++ if (err != 0) {
++ snd_printk(KERN_INFO "emu1010: Loading Firmware failed\n");
++ return err;
++ }
++
+ /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
+ snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
+ if ((reg & 0x3f) != 0x15) {
+diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
+index b14813d..c690b2a 100644
+--- a/sound/pci/hda/patch_hdmi.c
++++ b/sound/pci/hda/patch_hdmi.c
+@@ -1573,6 +1573,9 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)
+
+ if (pcmdev > 0)
+ sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev);
++ if (!is_jack_detectable(codec, per_pin->pin_nid))
++ strncat(hdmi_str, " Phantom",
++ sizeof(hdmi_str) - strlen(hdmi_str) - 1);
+
+ return snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str, 0);
+ }
diff --git a/3.8.2/4420_grsecurity-2.9.1-3.8.1-201303012255.patch b/3.8.2/4420_grsecurity-2.9.1-3.8.2-201303041742.patch
index b69296b..c57c85d 100644
--- a/3.8.2/4420_grsecurity-2.9.1-3.8.1-201303012255.patch
+++ b/3.8.2/4420_grsecurity-2.9.1-3.8.2-201303041742.patch
@@ -223,10 +223,10 @@ index b89a739..dba90c5 100644
+zconf.lex.c
zoffset.h
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
-index 6c72381..2fe9ae4 100644
+index 986614d..0afd461 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
-@@ -917,6 +917,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
+@@ -922,6 +922,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
Format: <unsigned int> such that (rxsize & ~0x1fffc0) == 0.
Default: 1024
@@ -237,7 +237,7 @@ index 6c72381..2fe9ae4 100644
hashdist= [KNL,NUMA] Large hashes allocated during boot
are distributed across NUMA nodes. Defaults on
for 64-bit NUMA, off otherwise.
-@@ -2116,6 +2120,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
+@@ -2121,6 +2125,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.
@@ -252,7 +252,7 @@ index 6c72381..2fe9ae4 100644
pcd. [PARIDE]
diff --git a/Makefile b/Makefile
-index 746c856..c014cfa 100644
+index 20d5318..19c7540 100644
--- a/Makefile
+++ b/Makefile
@@ -241,8 +241,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
@@ -2307,20 +2307,22 @@ index 96ee092..37f1844 100644
#define PSR_ENDIAN_MASK 0x00000200 /* Endianness state mask */
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
-index 60d3b73..9168db0 100644
+index 60d3b73..d27ee09 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
-@@ -89,8 +89,8 @@ EXPORT_SYMBOL(__memzero);
+@@ -89,9 +89,9 @@ EXPORT_SYMBOL(__memzero);
#ifdef CONFIG_MMU
EXPORT_SYMBOL(copy_page);
-EXPORT_SYMBOL(__copy_from_user);
-EXPORT_SYMBOL(__copy_to_user);
+-EXPORT_SYMBOL(__clear_user);
+EXPORT_SYMBOL(___copy_from_user);
+EXPORT_SYMBOL(___copy_to_user);
- EXPORT_SYMBOL(__clear_user);
++EXPORT_SYMBOL(___clear_user);
EXPORT_SYMBOL(__get_user_1);
+ EXPORT_SYMBOL(__get_user_2);
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 0f82098..3dbd3ee 100644
--- a/arch/arm/kernel/entry-armv.S
@@ -3267,6 +3269,30 @@ index 4653efb..8c60bf7 100644
/* omap_hwmod_list contains all registered struct omap_hwmods */
static LIST_HEAD(omap_hwmod_list);
+diff --git a/arch/arm/mach-omap2/wd_timer.c b/arch/arm/mach-omap2/wd_timer.c
+index 7c2b4ed..b2ea51f 100644
+--- a/arch/arm/mach-omap2/wd_timer.c
++++ b/arch/arm/mach-omap2/wd_timer.c
+@@ -110,7 +110,9 @@ static int __init omap_init_wdt(void)
+ struct omap_hwmod *oh;
+ char *oh_name = "wd_timer2";
+ char *dev_name = "omap_wdt";
+- struct omap_wd_timer_platform_data pdata;
++ static struct omap_wd_timer_platform_data pdata = {
++ .read_reset_sources = prm_read_reset_sources
++ };
+
+ if (!cpu_class_is_omap2() || of_have_populated_dt())
+ return 0;
+@@ -121,8 +123,6 @@ static int __init omap_init_wdt(void)
+ return -EINVAL;
+ }
+
+- pdata.read_reset_sources = prm_read_reset_sources;
+-
+ pdev = omap_device_build(dev_name, id, oh, &pdata,
+ sizeof(struct omap_wd_timer_platform_data),
+ NULL, 0, 0);
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h
index 6be4c4d..32ac32a 100644
--- a/arch/arm/mach-ux500/include/mach/setup.h
@@ -10070,10 +10096,10 @@ index 8a84501..b2d165f 100644
KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
GCOV_PROFILE := n
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
-index f8fa411..c570c53 100644
+index c205035..5853587 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
-@@ -145,7 +145,6 @@ again:
+@@ -150,7 +150,6 @@ again:
*addr = max_addr;
}
@@ -10081,7 +10107,7 @@ index f8fa411..c570c53 100644
efi_call_phys1(sys_table->boottime->free_pool, map);
fail:
-@@ -209,7 +208,6 @@ static efi_status_t low_alloc(unsigned long size, unsigned long align,
+@@ -214,7 +213,6 @@ static efi_status_t low_alloc(unsigned long size, unsigned long align,
if (i == map_size / desc_size)
status = EFI_NOT_FOUND;
@@ -16204,18 +16230,9 @@ index ef5ccca..bd83949 100644
}
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
-index b994cc8..812b537 100644
+index cbf5121..812b537 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
-@@ -131,7 +131,7 @@ static int __init parse_lapic(char *arg)
- {
- if (config_enabled(CONFIG_X86_32) && !arg)
- force_enable_local_apic = 1;
-- else if (!strncmp(arg, "notscdeadline", 13))
-+ else if (arg && !strncmp(arg, "notscdeadline", 13))
- setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE_TIMER);
- return 0;
- }
@@ -189,7 +189,7 @@ int first_system_vector = 0xfe;
/*
* Debug level, exported for io_apic.c
@@ -19375,91 +19392,6 @@ index 1d41402..af9a46a 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 48d9d4e..992f442 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_reserve(lowmem, 0x100000 - lowmem);
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c
index c18f59d..9c0c9f6 100644
--- a/arch/x86/kernel/head32.c
@@ -33418,10 +33350,10 @@ index 982f1f5..d21e5da 100644
iounmap(buf);
return 0;
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
-index f5596db..9355ce6 100644
+index bcb201c..f9782e5 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
-@@ -132,7 +132,7 @@ struct efivar_attribute {
+@@ -133,7 +133,7 @@ struct efivar_attribute {
};
static struct efivars __efivars;
@@ -34535,10 +34467,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 eb2ee11..6cc50ab 100644
+index ceb3040..6160c5c 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
-@@ -2240,7 +2240,7 @@ EXPORT_SYMBOL_GPL(hid_ignore);
+@@ -2242,7 +2242,7 @@ EXPORT_SYMBOL_GPL(hid_ignore);
int hid_add_device(struct hid_device *hdev)
{
@@ -34547,7 +34479,7 @@ index eb2ee11..6cc50ab 100644
int ret;
if (WARN_ON(hdev->status & HID_STAT_ADDED))
-@@ -2274,7 +2274,7 @@ int hid_add_device(struct hid_device *hdev)
+@@ -2276,7 +2276,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,
@@ -36416,7 +36348,7 @@ index 404f63a..4796533 100644
#if defined(CONFIG_DVB_DIB3000MB) || (defined(CONFIG_DVB_DIB3000MB_MODULE) && defined(MODULE))
extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
-index 35cc526..9d90d83 100644
+index 8e9a668..78d6310 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -63,7 +63,6 @@ enum omap_vout_channels {
@@ -36427,7 +36359,7 @@ index 35cc526..9d90d83 100644
/* Variables configurable through module params*/
static u32 video1_numbuffers = 3;
static u32 video2_numbuffers = 3;
-@@ -1010,6 +1009,12 @@ static int omap_vout_open(struct file *file)
+@@ -1012,6 +1011,12 @@ static int omap_vout_open(struct file *file)
{
struct videobuf_queue *q;
struct omap_vout_device *vout = NULL;
@@ -36440,7 +36372,7 @@ index 35cc526..9d90d83 100644
vout = video_drvdata(file);
v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__);
-@@ -1027,10 +1032,6 @@ static int omap_vout_open(struct file *file)
+@@ -1029,10 +1034,6 @@ static int omap_vout_open(struct file *file)
vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
q = &vout->vbq;
@@ -40439,10 +40371,10 @@ index 0d4aa82..f7832d4 100644
/* core tmem accessor functions */
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
-index f2aa754..11337b1 100644
+index 96f4981..4daaa7e 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
-@@ -1375,7 +1375,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
+@@ -1370,7 +1370,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
spin_lock_init(&dev->se_port_lock);
spin_lock_init(&dev->se_tmr_lock);
spin_lock_init(&dev->qf_cmd_lock);
@@ -47537,7 +47469,7 @@ index b2a34a1..162fa69 100644
return rc;
}
diff --git a/fs/exec.c b/fs/exec.c
-index 20df02c..1dff97d 100644
+index 20df02c..5af5d91 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -55,6 +55,17 @@
@@ -47606,8 +47538,8 @@ index 20df02c..1dff97d 100644
+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
+ // only allow 512KB for argv+env on suid/sgid binaries
+ // to prevent easy ASLR exhaustion
-+ if (((bprm->cred->euid != current_euid()) ||
-+ (bprm->cred->egid != current_egid())) &&
++ if (((!uid_eq(bprm->cred->euid, current_euid())) ||
++ (!gid_eq(bprm->cred->egid, current_egid()))) &&
+ (size > (512 * 1024))) {
+ put_page(page);
+ return NULL;
@@ -47930,7 +47862,7 @@ index 20df02c..1dff97d 100644
+ /* limit suid stack to 8MB
+ * we saved the old limits above and will restore them if this exec fails
+ */
-+ if (((bprm->cred->euid != current_euid()) || (bprm->cred->egid != current_egid())) &&
++ if (((!uid_eq(bprm->cred->euid, current_euid())) || (!gid_eq(bprm->cred->egid, current_egid()))) &&
+ (old_rlim[RLIMIT_STACK].rlim_cur > (8 * 1024 * 1024)))
+ current->signal->rlim[RLIMIT_STACK].rlim_cur = 8 * 1024 * 1024;
+#endif
@@ -48289,10 +48221,10 @@ index 22548f5..41521d8 100644
}
return 1;
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
-index cf18217..8f6b9c3 100644
+index 2f2e0da..89b113a 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
-@@ -498,8 +498,8 @@ static int ext4_has_free_clusters(struct ext4_sb_info *sbi,
+@@ -505,8 +505,8 @@ static int ext4_has_free_clusters(struct ext4_sb_info *sbi,
/* Hm, nope. Are (enough) root reserved clusters available? */
if (uid_eq(sbi->s_resuid, current_fsuid()) ||
(!gid_eq(sbi->s_resgid, GLOBAL_ROOT_GID) && in_group_p(sbi->s_resgid)) ||
@@ -48338,7 +48270,7 @@ index 8462eb3..4a71af6 100644
/* locality groups */
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
-index 1bf6fe7..1a5bdef 100644
+index 061727a..7622abf 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -1747,7 +1747,7 @@ void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac,
@@ -50125,10 +50057,10 @@ index e83351a..41e3c9c 100644
if (!ret)
ret = -EPIPE;
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
-index b7c09f9..3eff736 100644
+index 315e1f8..91f890c 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
-@@ -1226,7 +1226,7 @@ static char *read_link(struct dentry *dentry)
+@@ -1233,7 +1233,7 @@ static char *read_link(struct dentry *dentry)
return link;
}
@@ -51152,7 +51084,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,
@@ -51164,7 +51096,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;
}
@@ -51173,7 +51105,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);
@@ -51182,7 +51114,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;
}
@@ -51191,7 +51123,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)
@@ -51200,7 +51132,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);
@@ -51672,7 +51604,7 @@ index 6a91e6f..e54dbc14 100644
static struct pid *
get_children_pid(struct inode *inode, struct pid *pid_prev, loff_t pos)
diff --git a/fs/proc/base.c b/fs/proc/base.c
-index 9b43ff77..3d6a99f 100644
+index 9b43ff77..ba3e990 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -111,6 +111,14 @@ struct pid_entry {
@@ -51790,7 +51722,7 @@ index 9b43ff77..3d6a99f 100644
+ const struct cred *tmpcred = current_cred();
+ const struct cred *cred = __task_cred(task);
+
-+ if (!tmpcred->uid || (tmpcred->uid == cred->uid)
++ if (uid_eq(tmpcred->uid, GLOBAL_ROOT_UID) || uid_eq(tmpcred->uid, cred->uid)
+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
+ || in_group_p(grsec_proc_gid)
+#endif
@@ -52294,7 +52226,7 @@ index b1822dd..df622cb 100644
seq_putc(m, '\n');
diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c
-index fe72cd0..cb9b67d 100644
+index fe72cd0..21b52ff 100644
--- a/fs/proc/proc_net.c
+++ b/fs/proc/proc_net.c
@@ -23,6 +23,7 @@
@@ -52314,10 +52246,10 @@ index fe72cd0..cb9b67d 100644
+#endif
+
+#ifdef CONFIG_GRKERNSEC_PROC_USER
-+ if (cred->fsuid)
++ if (!uid_eq(cred->fsuid, GLOBAL_ROOT_UID))
+ return net;
+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
-+ if (cred->fsuid && !in_group_p(grsec_proc_gid))
++ if (!uid_eq(cred->fsuid, GLOBAL_ROOT_UID) && !in_group_p(grsec_proc_gid))
+ return net;
+#endif
@@ -53336,10 +53268,10 @@ index 9fbea87..6b19972 100644
struct posix_acl *acl;
struct posix_acl_entry *acl_e;
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
-index cdb2d33..704ce7f 100644
+index 572a858..12a9b0d 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
-@@ -189,7 +189,7 @@ xfs_bmap_validate_ret(
+@@ -192,7 +192,7 @@ xfs_bmap_validate_ret(
int nmap,
int ret_nmap);
#else
@@ -54468,10 +54400,10 @@ index 0000000..1b9afa9
+endif
diff --git a/grsecurity/gracl.c b/grsecurity/gracl.c
new file mode 100644
-index 0000000..69e1320
+index 0000000..6b7b8f7
--- /dev/null
+++ b/grsecurity/gracl.c
-@@ -0,0 +1,4019 @@
+@@ -0,0 +1,4067 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
@@ -56513,7 +56445,7 @@ index 0000000..69e1320
+ const struct cred *cred = current_cred();
+
+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
-+ cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
++ GR_GLOBAL_UID(cred->uid), GR_GLOBAL_GID(cred->gid), task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
+ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
+ 1UL, 1UL, gr_to_filename(dentry, mnt), (unsigned long) mode, &task->signal->saved_ip);
+
@@ -56521,16 +56453,29 @@ index 0000000..69e1320
+}
+
+static void
-+gr_log_learn_id_change(const char type, const unsigned int real,
-+ const unsigned int effective, const unsigned int fs)
++gr_log_learn_uid_change(const kuid_t real, const kuid_t effective, const kuid_t fs)
+{
+ struct task_struct *task = current;
+ const struct cred *cred = current_cred();
+
+ security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
-+ cred->uid, cred->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
++ GR_GLOBAL_UID(cred->uid), GR_GLOBAL_GID(cred->gid), task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
+ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
-+ type, real, effective, fs, &task->signal->saved_ip);
++ 'u', GR_GLOBAL_UID(real), GR_GLOBAL_UID(effective), GR_GLOBAL_UID(fs), &task->signal->saved_ip);
++
++ return;
++}
++
++static void
++gr_log_learn_gid_change(const kgid_t real, const kgid_t effective, const kgid_t fs)
++{
++ struct task_struct *task = current;
++ const struct cred *cred = current_cred();
++
++ security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
++ GR_GLOBAL_UID(cred->uid), GR_GLOBAL_GID(cred->gid), task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
++ task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
++ 'g', GR_GLOBAL_GID(real), GR_GLOBAL_GID(effective), GR_GLOBAL_GID(fs), &task->signal->saved_ip);
+
+ return;
+}
@@ -56803,23 +56748,28 @@ index 0000000..69e1320
+extern int __gr_process_user_ban(struct user_struct *user);
+
+int
-+gr_check_user_change(int real, int effective, int fs)
++gr_check_user_change(kuid_t real, kuid_t effective, kuid_t fs)
+{
+ unsigned int i;
+ __u16 num;
+ uid_t *uidlist;
-+ int curuid;
++ uid_t curuid;
+ int realok = 0;
+ int effectiveok = 0;
+ int fsok = 0;
++ uid_t globalreal, globaleffective, globalfs;
+
+#if defined(CONFIG_GRKERNSEC_KERN_LOCKOUT) || defined(CONFIG_GRKERNSEC_BRUTE)
+ struct user_struct *user;
+
-+ if (real == -1)
++ if (!uid_valid(real))
+ goto skipit;
+
-+ user = find_user(real);
++ /* find user based on global namespace */
++
++ globalreal = GR_GLOBAL_UID(real);
++
++ user = find_user(make_kuid(&init_user_ns, globalreal));
+ if (user == NULL)
+ goto skipit;
+
@@ -56839,7 +56789,7 @@ index 0000000..69e1320
+ return 0;
+
+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
-+ gr_log_learn_id_change('u', real, effective, fs);
++ gr_log_learn_uid_change(real, effective, fs);
+
+ num = current->acl->user_trans_num;
+ uidlist = current->acl->user_transitions;
@@ -56847,31 +56797,43 @@ index 0000000..69e1320
+ if (uidlist == NULL)
+ return 0;
+
-+ if (real == -1)
++ if (!uid_valid(real)) {
+ realok = 1;
-+ if (effective == -1)
++ globalreal = (uid_t)-1;
++ } else {
++ globalreal = GR_GLOBAL_UID(real);
++ }
++ if (!uid_valid(effective)) {
+ effectiveok = 1;
-+ if (fs == -1)
++ globaleffective = (uid_t)-1;
++ } else {
++ globaleffective = GR_GLOBAL_UID(effective);
++ }
++ if (!uid_valid(fs)) {
+ fsok = 1;
++ globalfs = (uid_t)-1;
++ } else {
++ globalfs = GR_GLOBAL_UID(fs);
++ }
+
+ if (current->acl->user_trans_type & GR_ID_ALLOW) {
+ for (i = 0; i < num; i++) {
-+ curuid = (int)uidlist[i];
-+ if (real == curuid)
++ curuid = uidlist[i];
++ if (globalreal == curuid)
+ realok = 1;
-+ if (effective == curuid)
++ if (globaleffective == curuid)
+ effectiveok = 1;
-+ if (fs == curuid)
++ if (globalfs == curuid)
+ fsok = 1;
+ }
+ } else if (current->acl->user_trans_type & GR_ID_DENY) {
+ for (i = 0; i < num; i++) {
-+ curuid = (int)uidlist[i];
-+ if (real == curuid)
++ curuid = uidlist[i];
++ if (globalreal == curuid)
+ break;
-+ if (effective == curuid)
++ if (globaleffective == curuid)
+ break;
-+ if (fs == curuid)
++ if (globalfs == curuid)
+ break;
+ }
+ /* not in deny list */
@@ -56885,27 +56847,28 @@ index 0000000..69e1320
+ if (realok && effectiveok && fsok)
+ return 0;
+ else {
-+ gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
++ gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : globalfs) : globaleffective) : globalreal);
+ return 1;
+ }
+}
+
+int
-+gr_check_group_change(int real, int effective, int fs)
++gr_check_group_change(kgid_t real, kgid_t effective, kgid_t fs)
+{
+ unsigned int i;
+ __u16 num;
+ gid_t *gidlist;
-+ int curgid;
++ gid_t curgid;
+ int realok = 0;
+ int effectiveok = 0;
+ int fsok = 0;
++ gid_t globalreal, globaleffective, globalfs;
+
+ if (unlikely(!(gr_status & GR_READY)))
+ return 0;
+
+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
-+ gr_log_learn_id_change('g', real, effective, fs);
++ gr_log_learn_gid_change(real, effective, fs);
+
+ num = current->acl->group_trans_num;
+ gidlist = current->acl->group_transitions;
@@ -56913,31 +56876,43 @@ index 0000000..69e1320
+ if (gidlist == NULL)
+ return 0;
+
-+ if (real == -1)
++ if (!gid_valid(real)) {
+ realok = 1;
-+ if (effective == -1)
++ globalreal = (gid_t)-1;
++ } else {
++ globalreal = GR_GLOBAL_GID(real);
++ }
++ if (!gid_valid(effective)) {
+ effectiveok = 1;
-+ if (fs == -1)
++ globaleffective = (gid_t)-1;
++ } else {
++ globaleffective = GR_GLOBAL_GID(effective);
++ }
++ if (!gid_valid(fs)) {
+ fsok = 1;
++ globalfs = (gid_t)-1;
++ } else {
++ globalfs = GR_GLOBAL_GID(fs);
++ }
+
+ if (current->acl->group_trans_type & GR_ID_ALLOW) {
+ for (i = 0; i < num; i++) {
-+ curgid = (int)gidlist[i];
-+ if (real == curgid)
++ curgid = gidlist[i];
++ if (globalreal == curgid)
+ realok = 1;
-+ if (effective == curgid)
++ if (globaleffective == curgid)
+ effectiveok = 1;
-+ if (fs == curgid)
++ if (globalfs == curgid)
+ fsok = 1;
+ }
+ } else if (current->acl->group_trans_type & GR_ID_DENY) {
+ for (i = 0; i < num; i++) {
-+ curgid = (int)gidlist[i];
-+ if (real == curgid)
++ curgid = gidlist[i];
++ if (globalreal == curgid)
+ break;
-+ if (effective == curgid)
++ if (globaleffective == curgid)
+ break;
-+ if (fs == curgid)
++ if (globalfs == curgid)
+ break;
+ }
+ /* not in deny list */
@@ -56951,7 +56926,7 @@ index 0000000..69e1320
+ if (realok && effectiveok && fsok)
+ return 0;
+ else {
-+ gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
++ gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : globalfs) : globaleffective) : globalreal);
+ return 1;
+ }
+}
@@ -56959,16 +56934,21 @@ index 0000000..69e1320
+extern int gr_acl_is_capable(const int cap);
+
+void
-+gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
++gr_set_role_label(struct task_struct *task, const kuid_t kuid, const kgid_t kgid)
+{
+ struct acl_role_label *role = task->role;
+ struct acl_subject_label *subj = NULL;
+ struct acl_object_label *obj;
+ struct file *filp;
++ uid_t uid;
++ gid_t gid;
+
+ if (unlikely(!(gr_status & GR_READY)))
+ return;
+
++ uid = GR_GLOBAL_UID(kuid);
++ gid = GR_GLOBAL_GID(kgid);
++
+ filp = task->exec_file;
+
+ /* kernel process, we'll give them the kernel role */
@@ -57922,7 +57902,7 @@ index 0000000..69e1320
+
+ if (task->exec_file) {
+ cred = __task_cred(task);
-+ task->role = lookup_acl_role_label(task, cred->uid, cred->gid);
++ task->role = lookup_acl_role_label(task, GR_GLOBAL_UID(cred->uid), GR_GLOBAL_GID(cred->gid));
+ ret = gr_apply_subject_to_task(task);
+ if (ret) {
+ read_unlock(&grsec_exec_file_lock);
@@ -58005,7 +57985,7 @@ index 0000000..69e1320
+ rcu_read_lock();
+ cred = __task_cred(task);
+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
-+ task->role->roletype, cred->uid, cred->gid, acl->filename,
++ task->role->roletype, GR_GLOBAL_UID(cred->uid), GR_GLOBAL_GID(cred->gid), acl->filename,
+ acl->filename, acl->res[res].rlim_cur, acl->res[res].rlim_max,
+ "", (unsigned long) res, &task->signal->saved_ip);
+ rcu_read_unlock();
@@ -58604,7 +58584,7 @@ index 0000000..34fefda
+}
diff --git a/grsecurity/gracl_cap.c b/grsecurity/gracl_cap.c
new file mode 100644
-index 0000000..6d21049
+index 0000000..bdd51ea
--- /dev/null
+++ b/grsecurity/gracl_cap.c
@@ -0,0 +1,110 @@
@@ -58659,8 +58639,8 @@ index 0000000..6d21049
+ if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
+ && cap_raised(cred->cap_effective, cap)) {
+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
-+ task->role->roletype, cred->uid,
-+ cred->gid, task->exec_file ?
++ task->role->roletype, GR_GLOBAL_UID(cred->uid),
++ GR_GLOBAL_GID(cred->gid), task->exec_file ?
+ gr_to_filename(task->exec_file->f_path.dentry,
+ task->exec_file->f_path.mnt) : curracl->filename,
+ curracl->filename, 0UL,
@@ -59157,7 +59137,7 @@ index 0000000..a340c17
+}
diff --git a/grsecurity/gracl_ip.c b/grsecurity/gracl_ip.c
new file mode 100644
-index 0000000..58800a7
+index 0000000..4699807
--- /dev/null
+++ b/grsecurity/gracl_ip.c
@@ -0,0 +1,384 @@
@@ -59277,8 +59257,8 @@ index 0000000..58800a7
+ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
+ __u32 fakeip = 0;
+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
-+ current->role->roletype, cred->uid,
-+ cred->gid, current->exec_file ?
++ current->role->roletype, GR_GLOBAL_UID(cred->uid),
++ GR_GLOBAL_GID(cred->gid), current->exec_file ?
+ gr_to_filename(current->exec_file->f_path.dentry,
+ current->exec_file->f_path.mnt) :
+ curr->filename, curr->filename,
@@ -59305,8 +59285,8 @@ index 0000000..58800a7
+ if (type == SOCK_RAW || type == SOCK_PACKET) {
+ __u32 fakeip = 0;
+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
-+ current->role->roletype, cred->uid,
-+ cred->gid, current->exec_file ?
++ current->role->roletype, GR_GLOBAL_UID(cred->uid),
++ GR_GLOBAL_GID(cred->gid), current->exec_file ?
+ gr_to_filename(current->exec_file->f_path.dentry,
+ current->exec_file->f_path.mnt) :
+ curr->filename, curr->filename,
@@ -59315,8 +59295,8 @@ index 0000000..58800a7
+ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
+ __u32 fakeip = 0;
+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
-+ current->role->roletype, cred->uid,
-+ cred->gid, current->exec_file ?
++ current->role->roletype, GR_GLOBAL_UID(cred->uid),
++ GR_GLOBAL_GID(cred->gid), current->exec_file ?
+ gr_to_filename(current->exec_file->f_path.dentry,
+ current->exec_file->f_path.mnt) :
+ curr->filename, curr->filename,
@@ -59412,8 +59392,8 @@ index 0000000..58800a7
+
+ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
-+ current->role->roletype, cred->uid,
-+ cred->gid, current->exec_file ?
++ current->role->roletype, GR_GLOBAL_UID(cred->uid),
++ GR_GLOBAL_GID(cred->gid), current->exec_file ?
+ gr_to_filename(current->exec_file->f_path.dentry,
+ current->exec_file->f_path.mnt) :
+ curr->filename, curr->filename,
@@ -59834,10 +59814,10 @@ index 0000000..39645c9
+}
diff --git a/grsecurity/gracl_segv.c b/grsecurity/gracl_segv.c
new file mode 100644
-index 0000000..25197e9
+index 0000000..10398db
--- /dev/null
+++ b/grsecurity/gracl_segv.c
-@@ -0,0 +1,299 @@
+@@ -0,0 +1,303 @@
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <asm/uaccess.h>
@@ -59939,9 +59919,10 @@ index 0000000..25197e9
+}
+
+static __inline__ void
-+gr_insert_uid(const uid_t uid, const unsigned long expires)
++gr_insert_uid(const kuid_t kuid, const unsigned long expires)
+{
+ int loc;
++ uid_t uid = GR_GLOBAL_UID(kuid);
+
+ if (uid_used == GR_UIDTABLE_MAX)
+ return;
@@ -59976,14 +59957,17 @@ index 0000000..25197e9
+}
+
+int
-+gr_check_crash_uid(const uid_t uid)
++gr_check_crash_uid(const kuid_t kuid)
+{
+ int loc;
+ int ret = 0;
++ uid_t uid;
+
+ if (unlikely(!gr_acl_is_enabled()))
+ return 0;
+
++ uid = GR_GLOBAL_UID(kuid);
++
+ spin_lock(&gr_uid_lock);
+ loc = gr_find_uid(uid);
+
@@ -60006,8 +59990,8 @@ index 0000000..25197e9
+ if (!uid_eq(cred->uid, cred->euid) || !uid_eq(cred->uid, cred->suid) ||
+ !uid_eq(cred->uid, cred->fsuid))
+ return 1;
-+ if (!uid_eq(cred->gid, cred->egid) || !uid_eq(cred->gid, cred->sgid) ||
-+ !uid_eq(cred->gid, cred->fsgid))
++ if (!gid_eq(cred->gid, cred->egid) || !gid_eq(cred->gid, cred->sgid) ||
++ !gid_eq(cred->gid, cred->fsgid))
+ return 1;
+
+ return 0;
@@ -60139,7 +60123,7 @@ index 0000000..25197e9
+}
diff --git a/grsecurity/gracl_shm.c b/grsecurity/gracl_shm.c
new file mode 100644
-index 0000000..9d83a69
+index 0000000..120978a
--- /dev/null
+++ b/grsecurity/gracl_shm.c
@@ -0,0 +1,40 @@
@@ -60154,7 +60138,7 @@ index 0000000..9d83a69
+
+int
+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
-+ const time_t shm_createtime, const uid_t cuid, const int shmid)
++ const time_t shm_createtime, const kuid_t cuid, const int shmid)
+{
+ struct task_struct *task;
+
@@ -60175,7 +60159,7 @@ index 0000000..9d83a69
+ (task->acl != current->acl))) {
+ read_unlock(&tasklist_lock);
+ rcu_read_unlock();
-+ gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
++ gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, GR_GLOBAL_UID(cuid), shm_cprid, shmid);
+ return 0;
+ }
+ read_unlock(&tasklist_lock);
@@ -60573,7 +60557,7 @@ index 0000000..70fe0ae
+}
diff --git a/grsecurity/grsec_disabled.c b/grsecurity/grsec_disabled.c
new file mode 100644
-index 0000000..e6796b3
+index 0000000..207d409
--- /dev/null
+++ b/grsecurity/grsec_disabled.c
@@ -0,0 +1,434 @@
@@ -60716,7 +60700,7 @@ index 0000000..e6796b3
+}
+
+int
-+gr_check_crash_uid(const uid_t uid)
++gr_check_crash_uid(const kuid_t uid)
+{
+ return 0;
+}
@@ -60893,7 +60877,7 @@ index 0000000..e6796b3
+
+int
+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
-+ const time_t shm_createtime, const uid_t cuid, const int shmid)
++ const time_t shm_createtime, const kuid_t cuid, const int shmid)
+{
+ return 1;
+}
@@ -60950,7 +60934,7 @@ index 0000000..e6796b3
+}
+
+void
-+gr_set_role_label(const uid_t uid, const gid_t gid)
++gr_set_role_label(const kuid_t uid, const kgid_t gid)
+{
+ return;
+}
@@ -60980,13 +60964,13 @@ index 0000000..e6796b3
+}
+
+int
-+gr_check_user_change(int real, int effective, int fs)
++gr_check_user_change(kuid_t real, kuid_t effective, kuid_t fs)
+{
+ return 0;
+}
+
+int
-+gr_check_group_change(int real, int effective, int fs)
++gr_check_group_change(kgid_t real, kgid_t effective, kgid_t fs)
+{
+ return 0;
+}
@@ -61193,7 +61177,7 @@ index 0000000..abfa971
+EXPORT_SYMBOL(gr_task_is_capable_nolog);
diff --git a/grsecurity/grsec_fifo.c b/grsecurity/grsec_fifo.c
new file mode 100644
-index 0000000..d3ee748
+index 0000000..06cc6ea
--- /dev/null
+++ b/grsecurity/grsec_fifo.c
@@ -0,0 +1,24 @@
@@ -61212,10 +61196,10 @@ index 0000000..d3ee748
+
+ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
+ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
-+ (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
-+ (cred->fsuid != dentry->d_inode->i_uid)) {
++ !uid_eq(dentry->d_inode->i_uid, dir->d_inode->i_uid) &&
++ !uid_eq(cred->fsuid, dentry->d_inode->i_uid)) {
+ if (!inode_permission(dentry->d_inode, acc_mode))
-+ gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
++ gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, GR_GLOBAL_UID(dentry->d_inode->i_uid), GR_GLOBAL_GID(dentry->d_inode->i_gid));
+ return -EACCES;
+ }
+#endif
@@ -61252,7 +61236,7 @@ index 0000000..8ca18bf
+}
diff --git a/grsecurity/grsec_init.c b/grsecurity/grsec_init.c
new file mode 100644
-index 0000000..05a6015
+index 0000000..a862e9f
--- /dev/null
+++ b/grsecurity/grsec_init.c
@@ -0,0 +1,283 @@
@@ -61268,7 +61252,7 @@ index 0000000..05a6015
+int grsec_enable_ptrace_readexec;
+int grsec_enable_setxid;
+int grsec_enable_symlinkown;
-+int grsec_symlinkown_gid;
++kgid_t grsec_symlinkown_gid;
+int grsec_enable_brute;
+int grsec_enable_link;
+int grsec_enable_dmesg;
@@ -61281,7 +61265,7 @@ index 0000000..05a6015
+int grsec_enable_time;
+int grsec_enable_audit_textrel;
+int grsec_enable_group;
-+int grsec_audit_gid;
++kgid_t grsec_audit_gid;
+int grsec_enable_chdir;
+int grsec_enable_mount;
+int grsec_enable_rofs;
@@ -61300,7 +61284,7 @@ index 0000000..05a6015
+int grsec_enable_chroot_sysctl;
+int grsec_enable_chroot_unix;
+int grsec_enable_tpe;
-+int grsec_tpe_gid;
++kgid_t grsec_tpe_gid;
+int grsec_enable_blackhole;
+#ifdef CONFIG_IPV6_MODULE
+EXPORT_SYMBOL(grsec_enable_blackhole);
@@ -61309,11 +61293,11 @@ index 0000000..05a6015
+int grsec_enable_tpe_all;
+int grsec_enable_tpe_invert;
+int grsec_enable_socket_all;
-+int grsec_socket_all_gid;
++kgid_t grsec_socket_all_gid;
+int grsec_enable_socket_client;
-+int grsec_socket_client_gid;
++kgid_t grsec_socket_client_gid;
+int grsec_enable_socket_server;
-+int grsec_socket_server_gid;
++kgid_t grsec_socket_server_gid;
+int grsec_resource_logging;
+int grsec_disable_privio;
+int grsec_enable_log_rwxmaps;
@@ -61419,7 +61403,7 @@ index 0000000..05a6015
+#endif
+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
+ grsec_enable_group = 1;
-+ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
++ grsec_audit_gid = KGIDT_INIT(CONFIG_GRKERNSEC_AUDIT_GID);
+#endif
+#ifdef CONFIG_GRKERNSEC_PTRACE_READEXEC
+ grsec_enable_ptrace_readexec = 1;
@@ -61514,26 +61498,26 @@ index 0000000..05a6015
+#endif
+#ifdef CONFIG_GRKERNSEC_SYMLINKOWN
+ grsec_enable_symlinkown = 1;
-+ grsec_symlinkown_gid = CONFIG_GRKERNSEC_SYMLINKOWN_GID;
++ grsec_symlinkown_gid = KGIDT_INIT(CONFIG_GRKERNSEC_SYMLINKOWN_GID);
+#endif
+#ifdef CONFIG_GRKERNSEC_TPE
+ grsec_enable_tpe = 1;
-+ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
++ grsec_tpe_gid = KGIDT_INIT(CONFIG_GRKERNSEC_TPE_GID);
+#ifdef CONFIG_GRKERNSEC_TPE_ALL
+ grsec_enable_tpe_all = 1;
+#endif
+#endif
+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
+ grsec_enable_socket_all = 1;
-+ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
++ grsec_socket_all_gid = KGIDT_INIT(CONFIG_GRKERNSEC_SOCKET_ALL_GID);
+#endif
+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
+ grsec_enable_socket_client = 1;
-+ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
++ grsec_socket_client_gid = KGIDT_INIT(CONFIG_GRKERNSEC_SOCKET_CLIENT_GID);
+#endif
+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
+ grsec_enable_socket_server = 1;
-+ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
++ grsec_socket_server_gid = KGIDT_INIT(CONFIG_GRKERNSEC_SOCKET_SERVER_GID);
+#endif
+#endif
+
@@ -61605,10 +61589,10 @@ index 0000000..6095407
+}
diff --git a/grsecurity/grsec_log.c b/grsecurity/grsec_log.c
new file mode 100644
-index 0000000..7bd6c2b
+index 0000000..7c06085
--- /dev/null
+++ b/grsecurity/grsec_log.c
-@@ -0,0 +1,329 @@
+@@ -0,0 +1,326 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/file.h>
@@ -61624,9 +61608,6 @@ index 0000000..7bd6c2b
+#define ENABLE_PREEMPT()
+#endif
+
-+#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 BEGIN_LOCKS(x) \
+ DISABLE_PREEMPT(); \
+ rcu_read_lock(); \
@@ -63107,7 +63088,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..07e0dc0
+index 0000000..ac20d7f
--- /dev/null
+++ b/grsecurity/grsec_tpe.c
@@ -0,0 +1,73 @@
@@ -63129,7 +63110,7 @@ index 0000000..07e0dc0
+ char *msg2 = NULL;
+
+ // never restrict root
-+ if (!cred->uid)
++ if (uid_eq(cred->uid, GLOBAL_ROOT_UID))
+ return 1;
+
+ if (grsec_enable_tpe) {
@@ -63150,7 +63131,7 @@ index 0000000..07e0dc0
+ if (!msg)
+ goto next_check;
+
-+ if (inode->i_uid)
++ if (!uid_eq(inode->i_uid, GLOBAL_ROOT_UID))
+ msg2 = "file in non-root-owned directory";
+ else if (inode->i_mode & S_IWOTH)
+ msg2 = "file in world-writable directory";
@@ -63169,7 +63150,7 @@ index 0000000..07e0dc0
+ if (!grsec_enable_tpe || !grsec_enable_tpe_all)
+ return 1;
+
-+ if (inode->i_uid && (inode->i_uid != cred->uid))
++ if (!uid_eq(inode->i_uid, GLOBAL_ROOT_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";
@@ -65046,7 +65027,7 @@ index 0000000..be66033
+#endif
diff --git a/include/linux/grinternal.h b/include/linux/grinternal.h
new file mode 100644
-index 0000000..baa6e96
+index 0000000..9bb6662
--- /dev/null
+++ b/include/linux/grinternal.h
@@ -0,0 +1,215 @@
@@ -65112,18 +65093,18 @@ index 0000000..baa6e96
+extern int grsec_enable_chroot_sysctl;
+extern int grsec_enable_chroot_unix;
+extern int grsec_enable_symlinkown;
-+extern int grsec_symlinkown_gid;
++extern kgid_t grsec_symlinkown_gid;
+extern int grsec_enable_tpe;
-+extern int grsec_tpe_gid;
++extern kgid_t grsec_tpe_gid;
+extern int grsec_enable_tpe_all;
+extern int grsec_enable_tpe_invert;
+extern int grsec_enable_socket_all;
-+extern int grsec_socket_all_gid;
++extern kgid_t grsec_socket_all_gid;
+extern int grsec_enable_socket_client;
-+extern int grsec_socket_client_gid;
++extern kgid_t grsec_socket_client_gid;
+extern int grsec_enable_socket_server;
-+extern int grsec_socket_server_gid;
-+extern int grsec_audit_gid;
++extern kgid_t grsec_socket_server_gid;
++extern kgid_t grsec_audit_gid;
+extern int grsec_enable_group;
+extern int grsec_enable_audit_textrel;
+extern int grsec_enable_log_rwxmaps;
@@ -65384,7 +65365,7 @@ index 0000000..2bd4c8d
+#define GR_BRUTE_DAEMON_MSG "bruteforce prevention initiated for the next 30 minutes or until service restarted, stalling each fork 30 seconds. Please investigate the crash report for "
diff --git a/include/linux/grsecurity.h b/include/linux/grsecurity.h
new file mode 100644
-index 0000000..c5e5913
+index 0000000..1ae241a
--- /dev/null
+++ b/include/linux/grsecurity.h
@@ -0,0 +1,257 @@
@@ -65432,8 +65413,8 @@ index 0000000..c5e5913
+
+int gr_acl_enable_at_secure(void);
+
-+int gr_check_user_change(int real, int effective, int fs);
-+int gr_check_group_change(int real, int effective, int fs);
++int gr_check_user_change(kuid_t real, kuid_t effective, kuid_t fs);
++int gr_check_group_change(kgid_t real, kgid_t effective, kgid_t fs);
+
+void gr_del_task_from_ip_table(struct task_struct *p);
+
@@ -65505,7 +65486,7 @@ index 0000000..c5e5913
+void gr_copy_label(struct task_struct *tsk);
+void gr_handle_crash(struct task_struct *task, const int sig);
+int gr_handle_signal(const struct task_struct *p, const int sig);
-+int gr_check_crash_uid(const uid_t uid);
++int gr_check_crash_uid(const kuid_t uid);
+int gr_check_protected_task(const struct task_struct *task);
+int gr_check_protected_task_fowner(struct pid *pid, enum pid_type type);
+int gr_acl_handle_mmap(const struct file *file,
@@ -65532,8 +65513,8 @@ index 0000000..c5e5913
+int gr_check_crash_exec(const struct file *filp);
+int gr_acl_is_enabled(void);
+void gr_set_kernel_label(struct task_struct *task);
-+void gr_set_role_label(struct task_struct *task, const uid_t uid,
-+ const gid_t gid);
++void gr_set_role_label(struct task_struct *task, const kuid_t uid,
++ const kgid_t gid);
+int gr_set_proc_label(const struct dentry *dentry,
+ const struct vfsmount *mnt,
+ const int unsafe_flags);
@@ -65633,7 +65614,7 @@ index 0000000..c5e5913
+extern int grsec_disable_privio;
+
+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
-+extern int grsec_proc_gid;
++extern kgid_t grsec_proc_gid;
+#endif
+
+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
@@ -67652,6 +67633,18 @@ index 5ca0951..ab496a5 100644
ret; \
})
+diff --git a/include/linux/uidgid.h b/include/linux/uidgid.h
+index 8e522cbc..1b67af5 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)
+
+ #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))
++
+ #endif /* _LINUX_UIDGID_H */
diff --git a/include/linux/unaligned/access_ok.h b/include/linux/unaligned/access_ok.h
index 99c1b4d..bb94261 100644
--- a/include/linux/unaligned/access_ok.h
@@ -68732,7 +68725,7 @@ index 0993a22..32ba2fe 100644
void *pmi_pal;
u8 *vbe_state_orig; /*
diff --git a/init/Kconfig b/init/Kconfig
-index be8b7f5..b13cb62 100644
+index be8b7f5..1eeca9b 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -990,6 +990,7 @@ endif # CGROUPS
@@ -68743,16 +68736,7 @@ index be8b7f5..b13cb62 100644
default n
help
Enables additional kernel features in a sake of checkpoint/restore.
-@@ -1079,6 +1080,8 @@ config UIDGID_CONVERTED
- depends on OCFS2_FS = n
- depends on XFS_FS = n
-
-+ depends on GRKERNSEC = n
-+
- config UIDGID_STRICT_TYPE_CHECKS
- bool "Require conversions between uid/gids and their internal representation"
- depends on UIDGID_CONVERTED
-@@ -1468,7 +1471,7 @@ config SLUB_DEBUG
+@@ -1468,7 +1469,7 @@ config SLUB_DEBUG
config COMPAT_BRK
bool "Disable heap randomization"
@@ -68761,7 +68745,7 @@ index be8b7f5..b13cb62 100644
help
Randomizing heap placement makes heap exploits harder, but it
also breaks ancient binaries (including anything libc5 based).
-@@ -1711,7 +1714,7 @@ config INIT_ALL_POSSIBLE
+@@ -1711,7 +1712,7 @@ config INIT_ALL_POSSIBLE
config STOP_MACHINE
bool
default y
@@ -69091,7 +69075,7 @@ index 84c6bf1..8899338 100644
next_state = Reset;
return 0;
diff --git a/init/main.c b/init/main.c
-index cee4b5c..47f445e 100644
+index cee4b5c..9c267d9 100644
--- a/init/main.c
+++ b/init/main.c
@@ -96,6 +96,8 @@ static inline void mark_rodata_ro(void) { }
@@ -69108,10 +69092,10 @@ index cee4b5c..47f445e 100644
__setup("reset_devices", set_reset_devices);
+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
-+int grsec_proc_gid = CONFIG_GRKERNSEC_PROC_GID;
++kgid_t grsec_proc_gid = KGIDT_INIT(CONFIG_GRKERNSEC_PROC_GID);
+static int __init setup_grsec_proc_gid(char *str)
+{
-+ grsec_proc_gid = (int)simple_strtol(str, NULL, 0);
++ grsec_proc_gid = KGIDT_INIT(simple_strtol(str, NULL, 0));
+ return 1;
+}
+__setup("grsec_proc_gid=", setup_grsec_proc_gid);
@@ -69334,7 +69318,7 @@ index 58d31f1..cce7a55 100644
sem_params.flg = semflg;
sem_params.u.nsems = nsems;
diff --git a/ipc/shm.c b/ipc/shm.c
-index 4fa6d8f..38dfd0c 100644
+index 4fa6d8f..55cff14 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -69,6 +69,14 @@ static void shm_destroy (struct ipc_namespace *ns, struct shmid_kernel *shp);
@@ -69343,7 +69327,7 @@ index 4fa6d8f..38dfd0c 100644
+#ifdef CONFIG_GRKERNSEC
+extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
-+ const time_t shm_createtime, const uid_t cuid,
++ const time_t shm_createtime, const kuid_t cuid,
+ const int shmid);
+extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
+ const time_t shm_createtime);
@@ -69599,10 +69583,10 @@ index 493d972..f87dfbd 100644
+ return ns_capable_nolog(ns, cap) && kuid_has_mapping(ns, inode->i_uid);
+}
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
-index 4855892..30d23b4 100644
+index 1e23664..570a83d 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
-@@ -5535,7 +5535,7 @@ static int cgroup_css_links_read(struct cgroup *cont,
+@@ -5543,7 +5543,7 @@ static int cgroup_css_links_read(struct cgroup *cont,
struct css_set *cg = link->cg;
struct task_struct *task;
int count = 0;
@@ -69794,7 +69778,7 @@ index 42e8fa0..9e7406b 100644
return -ENOMEM;
diff --git a/kernel/cred.c b/kernel/cred.c
-index e0573a4..eefe488 100644
+index e0573a4..3874e41 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -164,6 +164,16 @@ void exit_creds(struct task_struct *tsk)
@@ -69832,7 +69816,7 @@ index e0573a4..eefe488 100644
/* dumpability changes */
if (!uid_eq(old->euid, new->euid) ||
!gid_eq(old->egid, new->egid) ||
-@@ -479,6 +491,101 @@ int commit_creds(struct cred *new)
+@@ -479,6 +491,102 @@ int commit_creds(struct cred *new)
put_cred(old);
return 0;
}
@@ -69846,7 +69830,7 @@ index e0573a4..eefe488 100644
+
+ current->delayed_cred = NULL;
+
-+ if (current_uid() && new != NULL) {
++ if (!uid_eq(current_uid(), GLOBAL_ROOT_UID) && new != NULL) {
+ // from doing get_cred on it when queueing this
+ put_cred(new);
+ return;
@@ -69907,7 +69891,8 @@ index e0573a4..eefe488 100644
+ init_cred
+ */
+ if (grsec_enable_setxid && !current_is_single_threaded() &&
-+ !current_uid() && new->uid) {
++ uid_eq(current_uid(), GLOBAL_ROOT_UID) &&
++ !uid_eq(new->uid, GLOBAL_ROOT_UID)) {
+ schedule_it = 1;
+ }
+ ret = __commit_creds(new);
@@ -70639,7 +70624,7 @@ index 60f48fa..7f3a770 100644
static int
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
-index 2169fee..45c017a 100644
+index 2169fee..706ccca 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -11,6 +11,9 @@
@@ -70728,7 +70713,7 @@ index 2169fee..45c017a 100644
struct kallsym_iter *iter = m->private;
+#ifdef CONFIG_GRKERNSEC_HIDESYM
-+ if (current_uid())
++ if (!uid_eq(current_uid(), GLOBAL_ROOT_UID))
+ return 0;
+#endif
+
@@ -70782,7 +70767,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..3fe3781 100644
+index 0023a87..b893e79 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -74,7 +74,7 @@ static void free_modprobe_argv(struct subprocess_info *info)
@@ -70840,7 +70825,7 @@ index 0023a87..3fe3781 100644
return ret;
+#ifdef CONFIG_GRKERNSEC_MODHARDEN
-+ if (!current_uid()) {
++ if (uid_eq(current_uid(), GLOBAL_ROOT_UID)) {
+ /* hack to workaround consolekit/udisks stupidity */
+ read_lock(&tasklist_lock);
+ if (!strcmp(current->comm, "mount") &&
@@ -70885,12 +70870,12 @@ index 0023a87..3fe3781 100644
+ int ret;
+
+#ifdef CONFIG_GRKERNSEC_MODHARDEN
-+ if (current_uid()) {
++ if (!uid_eq(current_uid(), GLOBAL_ROOT_UID)) {
+ char module_param[MODULE_NAME_LEN];
+
+ memset(module_param, 0, sizeof(module_param));
+
-+ snprintf(module_param, sizeof(module_param) - 1, "grsec_modharden_normal%u_", current_uid());
++ snprintf(module_param, sizeof(module_param) - 1, "grsec_modharden_normal%u_", GR_GLOBAL_UID(current_uid()));
+
+ va_start(args, fmt);
+ ret = ____request_module(wait, module_param, fmt, args);
@@ -72087,7 +72072,7 @@ index 942ca27..111e609 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 @@
@@ -72170,7 +72155,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;
@@ -73541,7 +73526,7 @@ index 2f194e9..2c05ea9 100644
.priority = 10,
};
diff --git a/kernel/sys.c b/kernel/sys.c
-index 265b376..b0cd50d 100644
+index 265b376..4e42ef5 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -157,6 +157,12 @@ static int set_one_prio(struct task_struct *p, int niceval, int error)
@@ -73561,7 +73546,7 @@ index 265b376..b0cd50d 100644
goto error;
}
-+ if (gr_check_group_change(new->gid, new->egid, -1))
++ if (gr_check_group_change(new->gid, new->egid, INVALID_GID))
+ goto error;
+
if (rgid != (gid_t) -1 ||
@@ -73591,7 +73576,7 @@ index 265b376..b0cd50d 100644
goto error;
}
-+ if (gr_check_user_change(new->uid, new->euid, -1))
++ if (gr_check_user_change(new->uid, new->euid, INVALID_UID))
+ goto error;
+
if (!uid_eq(new->uid, old->uid)) {
@@ -73614,7 +73599,7 @@ index 265b376..b0cd50d 100644
goto error;
}
-+ if (gr_check_user_change(kruid, keuid, -1))
++ if (gr_check_user_change(kruid, keuid, INVALID_UID))
+ goto error;
+
if (ruid != (uid_t) -1) {
@@ -73624,7 +73609,7 @@ index 265b376..b0cd50d 100644
goto error;
}
-+ if (gr_check_group_change(krgid, kegid, -1))
++ if (gr_check_group_change(krgid, kegid, INVALID_GID))
+ goto error;
+
if (rgid != (gid_t) -1)
@@ -73634,7 +73619,7 @@ index 265b376..b0cd50d 100644
if (!uid_valid(kuid))
return old_fsuid;
-+ if (gr_check_user_change(-1, -1, kuid))
++ if (gr_check_user_change(INVALID_UID, INVALID_UID, kuid))
+ goto error;
+
new = prepare_creds();
@@ -73652,7 +73637,7 @@ index 265b376..b0cd50d 100644
if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->egid) ||
gid_eq(kgid, old->sgid) || gid_eq(kgid, old->fsgid) ||
nsown_capable(CAP_SETGID)) {
-+ if (gr_check_group_change(-1, -1, kgid))
++ if (gr_check_group_change(INVALID_GID, INVALID_GID, kgid))
+ goto error;
+
if (!gid_eq(kgid, old->fsgid)) {
@@ -73896,7 +73881,7 @@ index c88878d..99d321b 100644
EXPORT_SYMBOL(proc_doulongvec_minmax);
EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax);
diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c
-index 5a63844..a199f50 100644
+index 0ddf3a0..a199f50 100644
--- a/kernel/sysctl_binary.c
+++ b/kernel/sysctl_binary.c
@@ -989,7 +989,7 @@ static ssize_t bin_intvec(struct file *file,
@@ -73953,19 +73938,7 @@ index 5a63844..a199f50 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);
@@ -74236,7 +74209,7 @@ index c0bd030..62a1927 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 41473b4..325fcfc 100644
+index 43defd1..76da436 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1874,12 +1874,17 @@ ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec)
@@ -74279,7 +74252,7 @@ index 41473b4..325fcfc 100644
start_pg = ftrace_allocate_pages(count);
if (!start_pg)
-@@ -4541,8 +4548,6 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
+@@ -4559,8 +4566,6 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
static int ftrace_graph_active;
@@ -74288,7 +74261,7 @@ index 41473b4..325fcfc 100644
int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace)
{
return 0;
-@@ -4686,6 +4691,10 @@ ftrace_suspend_notifier_call(struct notifier_block *bl, unsigned long state,
+@@ -4704,6 +4709,10 @@ ftrace_suspend_notifier_call(struct notifier_block *bl, unsigned long state,
return NOTIFY_DONE;
}
@@ -74299,7 +74272,7 @@ index 41473b4..325fcfc 100644
int register_ftrace_graph(trace_func_graph_ret_t retfunc,
trace_func_graph_ent_t entryfunc)
{
-@@ -4699,7 +4708,6 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc,
+@@ -4717,7 +4726,6 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc,
goto out;
}
@@ -74955,26 +74928,6 @@ index 5e396ac..58d5de1 100644
err_printk(dev, NULL, "DMA-API: device driver maps memory from"
"stack [addr=%p]\n", addr);
}
-diff --git a/lib/idr.c b/lib/idr.c
-index 6482390..ca5aa00 100644
---- a/lib/idr.c
-+++ b/lib/idr.c
-@@ -625,7 +625,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;
diff --git a/lib/inflate.c b/lib/inflate.c
index 013a761..c28f3fc 100644
--- a/lib/inflate.c
@@ -76555,7 +76508,7 @@ index c9bd528..da8d069 100644
capable(CAP_IPC_LOCK))
ret = do_mlockall(flags);
diff --git a/mm/mmap.c b/mm/mmap.c
-index d1e4124..7d36e4f 100644
+index 8832b87..7d36e4f 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -32,6 +32,7 @@
@@ -77301,51 +77254,7 @@ index d1e4124..7d36e4f 100644
spin_unlock(&vma->vm_mm->page_table_lock);
perf_event_mmap(vma);
-@@ -2169,9 +2477,28 @@ int expand_downwards(struct vm_area_struct *vma,
- return error;
- }
-
-+/*
-+ * Note how expand_stack() refuses to expand the stack all the way to
-+ * abut the next virtual mapping, *unless* that mapping itself is also
-+ * a stack mapping. We want to leave room for a guard page, after all
-+ * (the guard page itself is not added here, that is done by the
-+ * actual page faulting logic)
-+ *
-+ * This matches the behavior of the guard page logic (see mm/memory.c:
-+ * check_stack_guard_page()), which only allows the guard page to be
-+ * removed under these circumstances.
-+ */
- #ifdef CONFIG_STACK_GROWSUP
- int expand_stack(struct vm_area_struct *vma, unsigned long address)
- {
-+ struct vm_area_struct *next;
-+
-+ address &= PAGE_MASK;
-+ next = vma->vm_next;
-+ if (next && next->vm_start == address + PAGE_SIZE) {
-+ if (!(next->vm_flags & VM_GROWSUP))
-+ return -ENOMEM;
-+ }
- return expand_upwards(vma, address);
- }
-
-@@ -2194,6 +2521,14 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr)
- #else
- int expand_stack(struct vm_area_struct *vma, unsigned long address)
- {
-+ struct vm_area_struct *prev;
-+
-+ address &= PAGE_MASK;
-+ prev = vma->vm_prev;
-+ if (prev && prev->vm_end == address) {
-+ if (!(prev->vm_flags & VM_GROWSDOWN))
-+ return -ENOMEM;
-+ }
- return expand_downwards(vma, address);
- }
-
-@@ -2236,6 +2571,13 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma)
+@@ -2263,6 +2571,13 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma)
do {
long nrpages = vma_pages(vma);
@@ -77359,7 +77268,7 @@ index d1e4124..7d36e4f 100644
if (vma->vm_flags & VM_ACCOUNT)
nr_accounted += nrpages;
vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
-@@ -2281,6 +2623,16 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -2308,6 +2623,16 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma,
insertion_point = (prev ? &prev->vm_next : &mm->mmap);
vma->vm_prev = NULL;
do {
@@ -77376,7 +77285,7 @@ index d1e4124..7d36e4f 100644
vma_rb_erase(vma, &mm->mm_rb);
mm->map_count--;
tail_vma = vma;
-@@ -2312,14 +2664,33 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+@@ -2339,14 +2664,33 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
struct vm_area_struct *new;
int err = -ENOMEM;
@@ -77410,7 +77319,7 @@ index d1e4124..7d36e4f 100644
/* most fields are the same, copy all, and then fixup */
*new = *vma;
-@@ -2332,6 +2703,22 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+@@ -2359,6 +2703,22 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
}
@@ -77433,7 +77342,7 @@ index d1e4124..7d36e4f 100644
pol = mpol_dup(vma_policy(vma));
if (IS_ERR(pol)) {
err = PTR_ERR(pol);
-@@ -2354,6 +2741,36 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+@@ -2381,6 +2741,36 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
else
err = vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
@@ -77470,7 +77379,7 @@ index d1e4124..7d36e4f 100644
/* Success. */
if (!err)
return 0;
-@@ -2363,10 +2780,18 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+@@ -2390,10 +2780,18 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
new->vm_ops->close(new);
if (new->vm_file)
fput(new->vm_file);
@@ -77490,7 +77399,7 @@ index d1e4124..7d36e4f 100644
kmem_cache_free(vm_area_cachep, new);
out_err:
return err;
-@@ -2379,6 +2804,15 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+@@ -2406,6 +2804,15 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long addr, int new_below)
{
@@ -77506,7 +77415,7 @@ index d1e4124..7d36e4f 100644
if (mm->map_count >= sysctl_max_map_count)
return -ENOMEM;
-@@ -2390,11 +2824,30 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
+@@ -2417,11 +2824,30 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
* work. This now handles partial unmappings.
* Jeremy Fitzhardinge <jeremy@goop.org>
*/
@@ -77537,7 +77446,7 @@ index d1e4124..7d36e4f 100644
if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
return -EINVAL;
-@@ -2469,6 +2922,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
+@@ -2496,6 +2922,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
/* Fix up all other VM information */
remove_vma_list(mm, vma);
@@ -77546,7 +77455,7 @@ index d1e4124..7d36e4f 100644
return 0;
}
-@@ -2477,6 +2932,13 @@ int vm_munmap(unsigned long start, size_t len)
+@@ -2504,6 +2932,13 @@ int vm_munmap(unsigned long start, size_t len)
int ret;
struct mm_struct *mm = current->mm;
@@ -77560,7 +77469,7 @@ index d1e4124..7d36e4f 100644
down_write(&mm->mmap_sem);
ret = do_munmap(mm, start, len);
up_write(&mm->mmap_sem);
-@@ -2490,16 +2952,6 @@ SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
+@@ -2517,16 +2952,6 @@ SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
return vm_munmap(addr, len);
}
@@ -77577,7 +77486,7 @@ index d1e4124..7d36e4f 100644
/*
* this is really a simplified "do_mmap". it only handles
* anonymous maps. eventually we may be able to do some
-@@ -2513,6 +2965,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len)
+@@ -2540,6 +2965,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len)
struct rb_node ** rb_link, * rb_parent;
pgoff_t pgoff = addr >> PAGE_SHIFT;
int error;
@@ -77585,7 +77494,7 @@ index d1e4124..7d36e4f 100644
len = PAGE_ALIGN(len);
if (!len)
-@@ -2520,16 +2973,30 @@ static unsigned long do_brk(unsigned long addr, unsigned long len)
+@@ -2547,16 +2973,30 @@ static unsigned long do_brk(unsigned long addr, unsigned long len)
flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
@@ -77617,7 +77526,7 @@ index d1e4124..7d36e4f 100644
locked += mm->locked_vm;
lock_limit = rlimit(RLIMIT_MEMLOCK);
lock_limit >>= PAGE_SHIFT;
-@@ -2546,21 +3013,20 @@ static unsigned long do_brk(unsigned long addr, unsigned long len)
+@@ -2573,21 +3013,20 @@ static unsigned long do_brk(unsigned long addr, unsigned long len)
/*
* Clear old maps. this also does some error checking for us
*/
@@ -77642,7 +77551,7 @@ index d1e4124..7d36e4f 100644
return -ENOMEM;
/* Can we just expand an old private anonymous mapping? */
-@@ -2574,7 +3040,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len)
+@@ -2601,7 +3040,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len)
*/
vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
if (!vma) {
@@ -77651,7 +77560,7 @@ index d1e4124..7d36e4f 100644
return -ENOMEM;
}
-@@ -2588,11 +3054,12 @@ static unsigned long do_brk(unsigned long addr, unsigned long len)
+@@ -2615,11 +3054,12 @@ static unsigned long do_brk(unsigned long addr, unsigned long len)
vma_link(mm, vma, prev, rb_link, rb_parent);
out:
perf_event_mmap(vma);
@@ -77666,7 +77575,7 @@ index d1e4124..7d36e4f 100644
return addr;
}
-@@ -2650,6 +3117,7 @@ void exit_mmap(struct mm_struct *mm)
+@@ -2677,6 +3117,7 @@ void exit_mmap(struct mm_struct *mm)
while (vma) {
if (vma->vm_flags & VM_ACCOUNT)
nr_accounted += vma_pages(vma);
@@ -77674,7 +77583,7 @@ index d1e4124..7d36e4f 100644
vma = remove_vma(vma);
}
vm_unacct_memory(nr_accounted);
-@@ -2666,6 +3134,13 @@ int insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma)
+@@ -2693,6 +3134,13 @@ int insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma)
struct vm_area_struct *prev;
struct rb_node **rb_link, *rb_parent;
@@ -77688,7 +77597,7 @@ index d1e4124..7d36e4f 100644
/*
* The vm_pgoff of a purely anonymous vma should be irrelevant
* until its first write fault, when page's anon_vma and index
-@@ -2689,7 +3164,21 @@ int insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma)
+@@ -2716,7 +3164,21 @@ int insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma)
security_vm_enough_memory_mm(mm, vma_pages(vma)))
return -ENOMEM;
@@ -77710,7 +77619,7 @@ index d1e4124..7d36e4f 100644
return 0;
}
-@@ -2709,6 +3198,8 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
+@@ -2736,6 +3198,8 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
struct mempolicy *pol;
bool faulted_in_anon_vma = true;
@@ -77719,7 +77628,7 @@ index d1e4124..7d36e4f 100644
/*
* If anonymous vma has not yet been faulted, update new pgoff
* to match new location, to increase its chance of merging.
-@@ -2775,6 +3266,39 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
+@@ -2802,6 +3266,39 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
return NULL;
}
@@ -77759,7 +77668,7 @@ index d1e4124..7d36e4f 100644
/*
* Return true if the calling process may expand its vm space by the passed
* number of pages
-@@ -2786,6 +3310,12 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages)
+@@ -2813,6 +3310,12 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages)
lim = rlimit(RLIMIT_AS) >> PAGE_SHIFT;
@@ -77772,7 +77681,7 @@ index d1e4124..7d36e4f 100644
if (cur + npages > lim)
return 0;
return 1;
-@@ -2856,6 +3386,22 @@ int install_special_mapping(struct mm_struct *mm,
+@@ -2883,6 +3386,22 @@ int install_special_mapping(struct mm_struct *mm,
vma->vm_start = addr;
vma->vm_end = addr + len;
@@ -85392,6 +85301,21 @@ index 38be92c..21f49ee 100644
.name = "smack",
.ptrace_access_check = smack_ptrace_access_check,
+diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c
+index 390c646..f2f8db3 100644
+--- a/security/tomoyo/mount.c
++++ b/security/tomoyo/mount.c
+@@ -118,6 +118,10 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r,
+ type == tomoyo_mounts[TOMOYO_MOUNT_MOVE]) {
+ need_dev = -1; /* dev_name is a directory */
+ } else {
++ if (!capable(CAP_SYS_ADMIN)) {
++ error = -EPERM;
++ goto out;
++ }
+ fstype = get_fs_type(type);
+ if (!fstype) {
+ error = -ENODEV;
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index a2ee362..5754f34 100644
--- a/security/tomoyo/tomoyo.c