commit:     7a6332fd8a40d691c130fd3f32d19fddb581c10b
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Mar 18 18:55:08 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Mar 18 18:55:08 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=7a6332fd

Linux patch 3.12.57

 0000_README              |    4 +
 1056_linux-3.12.57.patch | 3229 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 3233 insertions(+)

diff --git a/0000_README b/0000_README
index 3d5d7bf..5531cd4 100644
--- a/0000_README
+++ b/0000_README
@@ -266,6 +266,10 @@ Patch:  1055_linux-3.12.56.patch
 From:   http://www.kernel.org
 Desc:   Linux 3.12.56
 
+Patch:  1056_linux-3.12.57.patch
+From:   http://www.kernel.org
+Desc:   Linux 3.12.57
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1056_linux-3.12.57.patch b/1056_linux-3.12.57.patch
new file mode 100644
index 0000000..49c86a6
--- /dev/null
+++ b/1056_linux-3.12.57.patch
@@ -0,0 +1,3229 @@
+diff --git a/Documentation/filesystems/efivarfs.txt 
b/Documentation/filesystems/efivarfs.txt
+index c477af086e65..686a64bba775 100644
+--- a/Documentation/filesystems/efivarfs.txt
++++ b/Documentation/filesystems/efivarfs.txt
+@@ -14,3 +14,10 @@ filesystem.
+ efivarfs is typically mounted like this,
+ 
+       mount -t efivarfs none /sys/firmware/efi/efivars
++
++Due to the presence of numerous firmware bugs where removing non-standard
++UEFI variables causes the system firmware to fail to POST, efivarfs
++files that are not well-known standardized variables are created
++as immutable files.  This doesn't prevent removal - "chattr -i" will work -
++but it does prevent this kind of failure from being accomplished
++accidentally.
+diff --git a/Makefile b/Makefile
+index 34049410c565..af4cfc008e64 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 3
+ PATCHLEVEL = 12
+-SUBLEVEL = 56
++SUBLEVEL = 57
+ EXTRAVERSION =
+ NAME = One Giant Leap for Frogkind
+ 
+diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
+index 524841f02803..45c2cb00e180 100644
+--- a/arch/mips/kernel/traps.c
++++ b/arch/mips/kernel/traps.c
+@@ -681,15 +681,15 @@ static int simulate_sync(struct pt_regs *regs, unsigned 
int opcode)
+ asmlinkage void do_ov(struct pt_regs *regs)
+ {
+       enum ctx_state prev_state;
+-      siginfo_t info;
++      siginfo_t info = {
++              .si_signo = SIGFPE,
++              .si_code = FPE_INTOVF,
++              .si_addr = (void __user *)regs->cp0_epc,
++      };
+ 
+       prev_state = exception_enter();
+       die_if_kernel("Integer overflow", regs);
+ 
+-      info.si_code = FPE_INTOVF;
+-      info.si_signo = SIGFPE;
+-      info.si_errno = 0;
+-      info.si_addr = (void __user *) regs->cp0_epc;
+       force_sig_info(SIGFPE, &info, current);
+       exception_exit(prev_state);
+ }
+@@ -790,7 +790,7 @@ out:
+ static void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
+       const char *str)
+ {
+-      siginfo_t info;
++      siginfo_t info = { 0 };
+       char b[40];
+ 
+ #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
+@@ -817,7 +817,6 @@ static void do_trap_or_bp(struct pt_regs *regs, unsigned 
int code,
+               else
+                       info.si_code = FPE_INTOVF;
+               info.si_signo = SIGFPE;
+-              info.si_errno = 0;
+               info.si_addr = (void __user *) regs->cp0_epc;
+               force_sig_info(SIGFPE, &info, current);
+               break;
+diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
+index 6ee59a0eb268..48b4cf6b2a24 100644
+--- a/arch/powerpc/kernel/module_64.c
++++ b/arch/powerpc/kernel/module_64.c
+@@ -192,7 +192,7 @@ static void dedotify(Elf64_Sym *syms, unsigned int 
numsyms, char *strtab)
+               if (syms[i].st_shndx == SHN_UNDEF) {
+                       char *name = strtab + syms[i].st_name;
+                       if (name[0] == '.')
+-                              memmove(name, name+1, strlen(name));
++                              syms[i].st_name++;
+               }
+       }
+ }
+diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
+index 92a2e9333620..b74ac9c5710b 100644
+--- a/arch/x86/ia32/ia32entry.S
++++ b/arch/x86/ia32/ia32entry.S
+@@ -422,6 +422,7 @@ ENTRY(ia32_syscall)
+       /*CFI_REL_OFFSET        cs,CS-RIP*/
+       CFI_REL_OFFSET  rip,RIP-RIP
+       PARAVIRT_ADJUST_EXCEPTION_FRAME
++      ASM_CLAC                        /* Do this early to minimize exposure */
+       SWAPGS
+       /*
+        * No need to follow this irqs on/off section: the syscall
+diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
+index 33120100ff5e..06bd995071de 100644
+--- a/arch/x86/kernel/acpi/sleep.c
++++ b/arch/x86/kernel/acpi/sleep.c
+@@ -16,6 +16,7 @@
+ #include <asm/cacheflush.h>
+ #include <asm/realmode.h>
+ 
++#include <linux/ftrace.h>
+ #include "../../realmode/rm/wakeup.h"
+ #include "sleep.h"
+ 
+@@ -96,7 +97,13 @@ int x86_acpi_suspend_lowlevel(void)
+        saved_magic = 0x123456789abcdef0L;
+ #endif /* CONFIG_64BIT */
+ 
++      /*
++       * Pause/unpause graph tracing around do_suspend_lowlevel as it has
++       * inconsistent call/return info after it jumps to the wakeup vector.
++       */
++      pause_graph_tracing();
+       do_suspend_lowlevel();
++      unpause_graph_tracing();
+       return 0;
+ }
+ 
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index 53fede68963d..9e439266554d 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -1492,6 +1492,13 @@ static void add_atomic_switch_msr(struct vcpu_vmx *vmx, 
unsigned msr,
+                       return;
+               }
+               break;
++      case MSR_IA32_PEBS_ENABLE:
++              /* PEBS needs a quiescent period after being disabled (to write
++               * a record).  Disabling PEBS through VMX MSR swapping doesn't
++               * provide that period, so a CPU could write host's record into
++               * guest's memory.
++               */
++              wrmsrl(MSR_IA32_PEBS_ENABLE, 0);
+       }
+ 
+       for (i = 0; i < m->nr; ++i)
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index d3691ab6d6a0..356e78f2ad1a 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -1978,6 +1978,8 @@ static void accumulate_steal_time(struct kvm_vcpu *vcpu)
+ 
+ static void record_steal_time(struct kvm_vcpu *vcpu)
+ {
++      accumulate_steal_time(vcpu);
++
+       if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED))
+               return;
+ 
+@@ -2111,12 +2113,6 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct 
msr_data *msr_info)
+               if (!(data & KVM_MSR_ENABLED))
+                       break;
+ 
+-              vcpu->arch.st.last_steal = current->sched_info.run_delay;
+-
+-              preempt_disable();
+-              accumulate_steal_time(vcpu);
+-              preempt_enable();
+-
+               kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
+ 
+               break;
+@@ -2795,7 +2791,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+               vcpu->cpu = cpu;
+       }
+ 
+-      accumulate_steal_time(vcpu);
+       kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
+ }
+ 
+diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
+index 6fecf0bde105..1e82d2a1e205 100644
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -674,19 +674,18 @@ static int ata_ioc32(struct ata_port *ap)
+ int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev,
+                    int cmd, void __user *arg)
+ {
+-      int val = -EINVAL, rc = -EINVAL;
++      unsigned long val;
++      int rc = -EINVAL;
+       unsigned long flags;
+ 
+       switch (cmd) {
+-      case ATA_IOC_GET_IO32:
++      case HDIO_GET_32BIT:
+               spin_lock_irqsave(ap->lock, flags);
+               val = ata_ioc32(ap);
+               spin_unlock_irqrestore(ap->lock, flags);
+-              if (copy_to_user(arg, &val, 1))
+-                      return -EFAULT;
+-              return 0;
++              return put_user(val, (unsigned long __user *)arg);
+ 
+-      case ATA_IOC_SET_IO32:
++      case HDIO_SET_32BIT:
+               val = (unsigned long) arg;
+               rc = 0;
+               spin_lock_irqsave(ap->lock, flags);
+diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
+index 8c5a61ae03ea..d363009f8feb 100644
+--- a/drivers/firmware/efi/efivars.c
++++ b/drivers/firmware/efi/efivars.c
+@@ -219,7 +219,8 @@ efivar_store_raw(struct efivar_entry *entry, const char 
*buf, size_t count)
+       }
+ 
+       if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
+-          efivar_validate(new_var, new_var->Data, new_var->DataSize) == 
false) {
++          efivar_validate(new_var->VendorGuid, new_var->VariableName,
++                          new_var->Data, new_var->DataSize) == false) {
+               printk(KERN_ERR "efivars: Malformed variable content\n");
+               return -EINVAL;
+       }
+@@ -334,7 +335,8 @@ static ssize_t efivar_create(struct file *filp, struct 
kobject *kobj,
+               return -EACCES;
+ 
+       if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 ||
+-          efivar_validate(new_var, new_var->Data, new_var->DataSize) == 
false) {
++          efivar_validate(new_var->VendorGuid, new_var->VariableName,
++                          new_var->Data, new_var->DataSize) == false) {
+               printk(KERN_ERR "efivars: Malformed variable content\n");
+               return -EINVAL;
+       }
+@@ -409,35 +411,27 @@ efivar_create_sysfs_entry(struct efivar_entry *new_var)
+ {
+       int i, short_name_size;
+       char *short_name;
+-      unsigned long variable_name_size;
+-      efi_char16_t *variable_name;
+-
+-      variable_name = new_var->var.VariableName;
+-      variable_name_size = ucs2_strlen(variable_name) * sizeof(efi_char16_t);
++      unsigned long utf8_name_size;
++      efi_char16_t *variable_name = new_var->var.VariableName;
+ 
+       /*
+-       * Length of the variable bytes in ASCII, plus the '-' separator,
++       * Length of the variable bytes in UTF8, plus the '-' separator,
+        * plus the GUID, plus trailing NUL
+        */
+-      short_name_size = variable_name_size / sizeof(efi_char16_t)
+-                              + 1 + EFI_VARIABLE_GUID_LEN + 1;
+-
+-      short_name = kzalloc(short_name_size, GFP_KERNEL);
++      utf8_name_size = ucs2_utf8size(variable_name);
++      short_name_size = utf8_name_size + 1 + EFI_VARIABLE_GUID_LEN + 1;
+ 
++      short_name = kmalloc(short_name_size, GFP_KERNEL);
+       if (!short_name)
+               return 1;
+ 
+-      /* Convert Unicode to normal chars (assume top bits are 0),
+-         ala UTF-8 */
+-      for (i=0; i < (int)(variable_name_size / sizeof(efi_char16_t)); i++) {
+-              short_name[i] = variable_name[i] & 0xFF;
+-      }
++      ucs2_as_utf8(short_name, variable_name, short_name_size);
++
+       /* This is ugly, but necessary to separate one vendor's
+          private variables from another's.         */
+-
+-      *(short_name + strlen(short_name)) = '-';
++      short_name[utf8_name_size] = '-';
+       efi_guid_unparse(&new_var->var.VendorGuid,
+-                       short_name + strlen(short_name));
++                       short_name + utf8_name_size + 1);
+ 
+       new_var->kobj.kset = efivars_kset;
+ 
+diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
+index e6125522860a..4e2f46938bf0 100644
+--- a/drivers/firmware/efi/vars.c
++++ b/drivers/firmware/efi/vars.c
+@@ -42,7 +42,7 @@ DECLARE_WORK(efivar_work, NULL);
+ EXPORT_SYMBOL_GPL(efivar_work);
+ 
+ static bool
+-validate_device_path(struct efi_variable *var, int match, u8 *buffer,
++validate_device_path(efi_char16_t *var_name, int match, u8 *buffer,
+                    unsigned long len)
+ {
+       struct efi_generic_dev_path *node;
+@@ -75,7 +75,7 @@ validate_device_path(struct efi_variable *var, int match, u8 
*buffer,
+ }
+ 
+ static bool
+-validate_boot_order(struct efi_variable *var, int match, u8 *buffer,
++validate_boot_order(efi_char16_t *var_name, int match, u8 *buffer,
+                   unsigned long len)
+ {
+       /* An array of 16-bit integers */
+@@ -86,18 +86,18 @@ validate_boot_order(struct efi_variable *var, int match, 
u8 *buffer,
+ }
+ 
+ static bool
+-validate_load_option(struct efi_variable *var, int match, u8 *buffer,
++validate_load_option(efi_char16_t *var_name, int match, u8 *buffer,
+                    unsigned long len)
+ {
+       u16 filepathlength;
+       int i, desclength = 0, namelen;
+ 
+-      namelen = ucs2_strnlen(var->VariableName, sizeof(var->VariableName));
++      namelen = ucs2_strnlen(var_name, EFI_VAR_NAME_LEN);
+ 
+       /* Either "Boot" or "Driver" followed by four digits of hex */
+       for (i = match; i < match+4; i++) {
+-              if (var->VariableName[i] > 127 ||
+-                  hex_to_bin(var->VariableName[i] & 0xff) < 0)
++              if (var_name[i] > 127 ||
++                  hex_to_bin(var_name[i] & 0xff) < 0)
+                       return true;
+       }
+ 
+@@ -132,12 +132,12 @@ validate_load_option(struct efi_variable *var, int 
match, u8 *buffer,
+       /*
+        * And, finally, check the filepath
+        */
+-      return validate_device_path(var, match, buffer + desclength + 6,
++      return validate_device_path(var_name, match, buffer + desclength + 6,
+                                   filepathlength);
+ }
+ 
+ static bool
+-validate_uint16(struct efi_variable *var, int match, u8 *buffer,
++validate_uint16(efi_char16_t *var_name, int match, u8 *buffer,
+               unsigned long len)
+ {
+       /* A single 16-bit integer */
+@@ -148,7 +148,7 @@ validate_uint16(struct efi_variable *var, int match, u8 
*buffer,
+ }
+ 
+ static bool
+-validate_ascii_string(struct efi_variable *var, int match, u8 *buffer,
++validate_ascii_string(efi_char16_t *var_name, int match, u8 *buffer,
+                     unsigned long len)
+ {
+       int i;
+@@ -165,67 +165,133 @@ validate_ascii_string(struct efi_variable *var, int 
match, u8 *buffer,
+ }
+ 
+ struct variable_validate {
++      efi_guid_t vendor;
+       char *name;
+-      bool (*validate)(struct efi_variable *var, int match, u8 *data,
++      bool (*validate)(efi_char16_t *var_name, int match, u8 *data,
+                        unsigned long len);
+ };
+ 
++/*
++ * This is the list of variables we need to validate, as well as the
++ * whitelist for what we think is safe not to default to immutable.
++ *
++ * If it has a validate() method that's not NULL, it'll go into the
++ * validation routine.  If not, it is assumed valid, but still used for
++ * whitelisting.
++ *
++ * Note that it's sorted by {vendor,name}, but globbed names must come after
++ * any other name with the same prefix.
++ */
+ static const struct variable_validate variable_validate[] = {
+-      { "BootNext", validate_uint16 },
+-      { "BootOrder", validate_boot_order },
+-      { "DriverOrder", validate_boot_order },
+-      { "Boot*", validate_load_option },
+-      { "Driver*", validate_load_option },
+-      { "ConIn", validate_device_path },
+-      { "ConInDev", validate_device_path },
+-      { "ConOut", validate_device_path },
+-      { "ConOutDev", validate_device_path },
+-      { "ErrOut", validate_device_path },
+-      { "ErrOutDev", validate_device_path },
+-      { "Timeout", validate_uint16 },
+-      { "Lang", validate_ascii_string },
+-      { "PlatformLang", validate_ascii_string },
+-      { "", NULL },
++      { EFI_GLOBAL_VARIABLE_GUID, "BootNext", validate_uint16 },
++      { EFI_GLOBAL_VARIABLE_GUID, "BootOrder", validate_boot_order },
++      { EFI_GLOBAL_VARIABLE_GUID, "Boot*", validate_load_option },
++      { EFI_GLOBAL_VARIABLE_GUID, "DriverOrder", validate_boot_order },
++      { EFI_GLOBAL_VARIABLE_GUID, "Driver*", validate_load_option },
++      { EFI_GLOBAL_VARIABLE_GUID, "ConIn", validate_device_path },
++      { EFI_GLOBAL_VARIABLE_GUID, "ConInDev", validate_device_path },
++      { EFI_GLOBAL_VARIABLE_GUID, "ConOut", validate_device_path },
++      { EFI_GLOBAL_VARIABLE_GUID, "ConOutDev", validate_device_path },
++      { EFI_GLOBAL_VARIABLE_GUID, "ErrOut", validate_device_path },
++      { EFI_GLOBAL_VARIABLE_GUID, "ErrOutDev", validate_device_path },
++      { EFI_GLOBAL_VARIABLE_GUID, "Lang", validate_ascii_string },
++      { EFI_GLOBAL_VARIABLE_GUID, "OsIndications", NULL },
++      { EFI_GLOBAL_VARIABLE_GUID, "PlatformLang", validate_ascii_string },
++      { EFI_GLOBAL_VARIABLE_GUID, "Timeout", validate_uint16 },
++      { LINUX_EFI_CRASH_GUID, "*", NULL },
++      { NULL_GUID, "", NULL },
+ };
+ 
++static bool
++variable_matches(const char *var_name, size_t len, const char *match_name,
++               int *match)
++{
++      for (*match = 0; ; (*match)++) {
++              char c = match_name[*match];
++              char u = var_name[*match];
++
++              /* Wildcard in the matching name means we've matched */
++              if (c == '*')
++                      return true;
++
++              /* Case sensitive match */
++              if (!c && *match == len)
++                      return true;
++
++              if (c != u)
++                      return false;
++
++              if (!c)
++                      return true;
++      }
++      return true;
++}
++
+ bool
+-efivar_validate(struct efi_variable *var, u8 *data, unsigned long len)
++efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data,
++              unsigned long data_size)
+ {
+       int i;
+-      u16 *unicode_name = var->VariableName;
++      unsigned long utf8_size;
++      u8 *utf8_name;
+ 
+-      for (i = 0; variable_validate[i].validate != NULL; i++) {
+-              const char *name = variable_validate[i].name;
+-              int match;
++      utf8_size = ucs2_utf8size(var_name);
++      utf8_name = kmalloc(utf8_size + 1, GFP_KERNEL);
++      if (!utf8_name)
++              return false;
+ 
+-              for (match = 0; ; match++) {
+-                      char c = name[match];
+-                      u16 u = unicode_name[match];
++      ucs2_as_utf8(utf8_name, var_name, utf8_size);
++      utf8_name[utf8_size] = '\0';
+ 
+-                      /* All special variables are plain ascii */
+-                      if (u > 127)
+-                              return true;
++      for (i = 0; variable_validate[i].name[0] != '\0'; i++) {
++              const char *name = variable_validate[i].name;
++              int match = 0;
+ 
+-                      /* Wildcard in the matching name means we've matched */
+-                      if (c == '*')
+-                              return variable_validate[i].validate(var,
+-                                                           match, data, len);
++              if (efi_guidcmp(vendor, variable_validate[i].vendor))
++                      continue;
+ 
+-                      /* Case sensitive match */
+-                      if (c != u)
++              if (variable_matches(utf8_name, utf8_size+1, name, &match)) {
++                      if (variable_validate[i].validate == NULL)
+                               break;
+-
+-                      /* Reached the end of the string while matching */
+-                      if (!c)
+-                              return variable_validate[i].validate(var,
+-                                                           match, data, len);
++                      kfree(utf8_name);
++                      return variable_validate[i].validate(var_name, match,
++                                                           data, data_size);
+               }
+       }
+-
++      kfree(utf8_name);
+       return true;
+ }
+ EXPORT_SYMBOL_GPL(efivar_validate);
+ 
++bool
++efivar_variable_is_removable(efi_guid_t vendor, const char *var_name,
++                           size_t len)
++{
++      int i;
++      bool found = false;
++      int match = 0;
++
++      /*
++       * Check if our variable is in the validated variables list
++       */
++      for (i = 0; variable_validate[i].name[0] != '\0'; i++) {
++              if (efi_guidcmp(variable_validate[i].vendor, vendor))
++                      continue;
++
++              if (variable_matches(var_name, len,
++                                   variable_validate[i].name, &match)) {
++                      found = true;
++                      break;
++              }
++      }
++
++      /*
++       * If it's in our list, it is removable.
++       */
++      return found;
++}
++EXPORT_SYMBOL_GPL(efivar_variable_is_removable);
++
+ static efi_status_t
+ check_var_size(u32 attributes, unsigned long size)
+ {
+@@ -805,7 +871,7 @@ int efivar_entry_set_get_size(struct efivar_entry *entry, 
u32 attributes,
+ 
+       *set = false;
+ 
+-      if (efivar_validate(&entry->var, data, *size) == false)
++      if (efivar_validate(*vendor, name, data, *size) == false)
+               return -EINVAL;
+ 
+       /*
+diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
+index 48f7ad1497c2..88fc3a5fa7c4 100644
+--- a/drivers/gpu/drm/ast/ast_main.c
++++ b/drivers/gpu/drm/ast/ast_main.c
+@@ -124,7 +124,7 @@ static int ast_get_dram_info(struct drm_device *dev)
+       } while (ast_read32(ast, 0x10000) != 0x01);
+       data = ast_read32(ast, 0x10004);
+ 
+-      if (data & 0x400)
++      if (data & 0x40)
+               ast->dram_bus_width = 16;
+       else
+               ast->dram_bus_width = 32;
+diff --git a/drivers/gpu/drm/radeon/radeon_sa.c 
b/drivers/gpu/drm/radeon/radeon_sa.c
+index bb166849aa6e..f0bac68254b7 100644
+--- a/drivers/gpu/drm/radeon/radeon_sa.c
++++ b/drivers/gpu/drm/radeon/radeon_sa.c
+@@ -349,13 +349,8 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
+                       /* see if we can skip over some allocations */
+               } while (radeon_sa_bo_next_hole(sa_manager, fences, tries));
+ 
+-              for (i = 0; i < RADEON_NUM_RINGS; ++i)
+-                      radeon_fence_ref(fences[i]);
+-
+               spin_unlock(&sa_manager->wq.lock);
+               r = radeon_fence_wait_any(rdev, fences, false);
+-              for (i = 0; i < RADEON_NUM_RINGS; ++i)
+-                      radeon_fence_unref(&fences[i]);
+               spin_lock(&sa_manager->wq.lock);
+               /* if we have nothing to wait for block */
+               if (r == -ENOENT && block) {
+diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
+index 8f798be6e398..9afa397df661 100644
+--- a/drivers/iommu/amd_iommu_init.c
++++ b/drivers/iommu/amd_iommu_init.c
+@@ -227,6 +227,10 @@ static enum iommu_init_state init_state = 
IOMMU_START_STATE;
+ static int amd_iommu_enable_interrupts(void);
+ static int __init iommu_go_to_state(enum iommu_init_state state);
+ 
++static int iommu_pc_get_set_reg_val(struct amd_iommu *iommu,
++                                  u8 bank, u8 cntr, u8 fxn,
++                                  u64 *value, bool is_write);
++
+ static inline void update_last_devid(u16 devid)
+ {
+       if (devid > amd_iommu_last_bdf)
+@@ -1183,8 +1187,8 @@ static void init_iommu_perf_ctr(struct amd_iommu *iommu)
+       amd_iommu_pc_present = true;
+ 
+       /* Check if the performance counters can be written to */
+-      if ((0 != amd_iommu_pc_get_set_reg_val(0, 0, 0, 0, &val, true)) ||
+-          (0 != amd_iommu_pc_get_set_reg_val(0, 0, 0, 0, &val2, false)) ||
++      if ((0 != iommu_pc_get_set_reg_val(iommu, 0, 0, 0, &val, true)) ||
++          (0 != iommu_pc_get_set_reg_val(iommu, 0, 0, 0, &val2, false)) ||
+           (val != val2)) {
+               pr_err("AMD-Vi: Unable to write to IOMMU perf counter.\n");
+               amd_iommu_pc_present = false;
+@@ -2315,22 +2319,15 @@ u8 amd_iommu_pc_get_max_counters(u16 devid)
+ }
+ EXPORT_SYMBOL(amd_iommu_pc_get_max_counters);
+ 
+-int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn,
++static int iommu_pc_get_set_reg_val(struct amd_iommu *iommu,
++                                  u8 bank, u8 cntr, u8 fxn,
+                                   u64 *value, bool is_write)
+ {
+-      struct amd_iommu *iommu;
+       u32 offset;
+       u32 max_offset_lim;
+ 
+-      /* Make sure the IOMMU PC resource is available */
+-      if (!amd_iommu_pc_present)
+-              return -ENODEV;
+-
+-      /* Locate the iommu associated with the device ID */
+-      iommu = amd_iommu_rlookup_table[devid];
+-
+       /* Check for valid iommu and pc register indexing */
+-      if (WARN_ON((iommu == NULL) || (fxn > 0x28) || (fxn & 7)))
++      if (WARN_ON((fxn > 0x28) || (fxn & 7)))
+               return -ENODEV;
+ 
+       offset = (u32)(((0x40|bank) << 12) | (cntr << 8) | fxn);
+@@ -2354,3 +2351,16 @@ int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 
cntr, u8 fxn,
+       return 0;
+ }
+ EXPORT_SYMBOL(amd_iommu_pc_get_set_reg_val);
++
++int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn,
++                                  u64 *value, bool is_write)
++{
++      struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
++
++      /* Make sure the IOMMU PC resource is available */
++      if (!amd_iommu_pc_present || iommu == NULL)
++              return -ENODEV;
++
++      return iommu_pc_get_set_reg_val(iommu, bank, cntr, fxn,
++                                      value, is_write);
++}
+diff --git a/drivers/media/usb/usbvision/usbvision-video.c 
b/drivers/media/usb/usbvision/usbvision-video.c
+index ea5ec8ed67a7..3cf12da58787 100644
+--- a/drivers/media/usb/usbvision/usbvision-video.c
++++ b/drivers/media/usb/usbvision/usbvision-video.c
+@@ -1538,6 +1538,13 @@ static int usbvision_probe(struct usb_interface *intf,
+       printk(KERN_INFO "%s: %s found\n", __func__,
+                               usbvision_device_data[model].model_string);
+ 
++      /*
++       * this is a security check.
++       * an exploit using an incorrect bInterfaceNumber is known
++       */
++      if (ifnum >= USB_MAXINTERFACES || !dev->actconfig->interface[ifnum])
++              return -ENODEV;
++
+       if (usbvision_device_data[model].interface >= 0)
+               interface = 
&dev->actconfig->interface[usbvision_device_data[model].interface]->altsetting[0];
+       else
+diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c
+index 2a1b6e037e1a..0134ba32a057 100644
+--- a/drivers/mtd/ubi/upd.c
++++ b/drivers/mtd/ubi/upd.c
+@@ -193,7 +193,7 @@ int ubi_start_leb_change(struct ubi_device *ubi, struct 
ubi_volume *vol,
+       vol->changing_leb = 1;
+       vol->ch_lnum = req->lnum;
+ 
+-      vol->upd_buf = vmalloc(req->bytes);
++      vol->upd_buf = vmalloc(ALIGN((int)req->bytes, ubi->min_io_size));
+       if (!vol->upd_buf)
+               return -ENOMEM;
+ 
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
+index 05e23b80b5e3..a5cc8a674e06 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
+@@ -222,13 +222,13 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 
pfc_en, u8 *prio_tc)
+       reg |= IXGBE_MFLCN_DPF;
+ 
+       /*
+-       * X540 supports per TC Rx priority flow control.  So
+-       * clear all TCs and only enable those that should be
++       * X540 & X550 supports per TC Rx priority flow control.
++       * So clear all TCs and only enable those that should be
+        * enabled.
+        */
+       reg &= ~(IXGBE_MFLCN_RPFCE_MASK | IXGBE_MFLCN_RFCE);
+ 
+-      if (hw->mac.type == ixgbe_mac_X540)
++      if (hw->mac.type >= ixgbe_mac_X540)
+               reg |= pfc_en << IXGBE_MFLCN_RPFCE_SHIFT;
+ 
+       if (pfc_en)
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
+index f58db453a97e..68bdcb138334 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
+@@ -75,7 +75,7 @@ int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid)
+       if (!netdev)
+               goto out_ddp_put;
+ 
+-      if (xid >= IXGBE_FCOE_DDP_MAX)
++      if (xid >= netdev->fcoe_ddp_xid)
+               goto out_ddp_put;
+ 
+       adapter = netdev_priv(netdev);
+@@ -150,7 +150,7 @@ static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, 
u16 xid,
+               return 0;
+ 
+       adapter = netdev_priv(netdev);
+-      if (xid >= IXGBE_FCOE_DDP_MAX) {
++      if (xid >= netdev->fcoe_ddp_xid) {
+               e_warn(drv, "xid=0x%x out-of-range\n", xid);
+               return 0;
+       }
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 3afe47870e95..a7de5daae6d3 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -3167,7 +3167,7 @@ static int finish_port_resume(struct usb_device *udev)
+ /*
+  * There are some SS USB devices which take longer time for link training.
+  * XHCI specs 4.19.4 says that when Link training is successful, port
+- * sets CSC bit to 1. So if SW reads port status before successful link
++ * sets CCS bit to 1. So if SW reads port status before successful link
+  * training, then it will not find device to be present.
+  * USB Analyzer log with such buggy devices show that in some cases
+  * device switch on the RX termination after long delay of host enabling
+@@ -3178,14 +3178,17 @@ static int finish_port_resume(struct usb_device *udev)
+  * routine implements a 2000 ms timeout for link training. If in a case
+  * link trains before timeout, loop will exit earlier.
+  *
++ * There are also some 2.0 hard drive based devices and 3.0 thumb
++ * drives that, when plugged into a 2.0 only port, take a long
++ * time to set CCS after VBUS enable.
++ *
+  * FIXME: If a device was connected before suspend, but was removed
+  * while system was asleep, then the loop in the following routine will
+  * only exit at timeout.
+  *
+- * This routine should only be called when persist is enabled for a SS
+- * device.
++ * This routine should only be called when persist is enabled.
+  */
+-static int wait_for_ss_port_enable(struct usb_device *udev,
++static int wait_for_connected(struct usb_device *udev,
+               struct usb_hub *hub, int *port1,
+               u16 *portchange, u16 *portstatus)
+ {
+@@ -3198,6 +3201,7 @@ static int wait_for_ss_port_enable(struct usb_device 
*udev,
+               delay_ms += 20;
+               status = hub_port_status(hub, *port1, portstatus, portchange);
+       }
++      dev_dbg(&udev->dev, "Waited %dms for CONNECT\n", delay_ms);
+       return status;
+ }
+ 
+@@ -3303,8 +3307,8 @@ int usb_port_resume(struct usb_device *udev, 
pm_message_t msg)
+ 
+       clear_bit(port1, hub->busy_bits);
+ 
+-      if (udev->persist_enabled && hub_is_superspeed(hub->hdev))
+-              status = wait_for_ss_port_enable(udev, hub, &port1, &portchange,
++      if (udev->persist_enabled)
++              status = wait_for_connected(udev, hub, &port1, &portchange,
+                               &portstatus);
+ 
+       status = check_port_resume_type(udev,
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index f288f3c1f5e2..26bcd501f314 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -43,8 +43,8 @@ static int cp210x_tiocmset(struct tty_struct *, unsigned 
int, unsigned int);
+ static int cp210x_tiocmset_port(struct usb_serial_port *port,
+               unsigned int, unsigned int);
+ static void cp210x_break_ctl(struct tty_struct *, int);
+-static int cp210x_startup(struct usb_serial *);
+-static void cp210x_release(struct usb_serial *);
++static int cp210x_port_probe(struct usb_serial_port *);
++static int cp210x_port_remove(struct usb_serial_port *);
+ static void cp210x_dtr_rts(struct usb_serial_port *p, int on);
+ 
+ static const struct usb_device_id id_table[] = {
+@@ -164,6 +164,7 @@ static const struct usb_device_id id_table[] = {
+       { USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */
+       { USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */
+       { USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */
++      { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
+       { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
+       { USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
+       { USB_DEVICE(0x1BA4, 0x0002) }, /* Silicon Labs 358x factory default */
+@@ -200,8 +201,9 @@ static const struct usb_device_id id_table[] = {
+ 
+ MODULE_DEVICE_TABLE(usb, id_table);
+ 
+-struct cp210x_serial_private {
++struct cp210x_port_private {
+       __u8                    bInterfaceNumber;
++      bool                    has_swapped_line_ctl;
+ };
+ 
+ static struct usb_serial_driver cp210x_device = {
+@@ -219,8 +221,8 @@ static struct usb_serial_driver cp210x_device = {
+       .set_termios            = cp210x_set_termios,
+       .tiocmget               = cp210x_tiocmget,
+       .tiocmset               = cp210x_tiocmset,
+-      .attach                 = cp210x_startup,
+-      .release                = cp210x_release,
++      .port_probe             = cp210x_port_probe,
++      .port_remove            = cp210x_port_remove,
+       .dtr_rts                = cp210x_dtr_rts
+ };
+ 
+@@ -304,6 +306,14 @@ static struct usb_serial_driver * const serial_drivers[] 
= {
+ #define CONTROL_WRITE_RTS     0x0200
+ 
+ /*
++ * CP210X_PURGE - 16 bits passed in wValue of USB request.
++ * SiLabs app note AN571 gives a strange description of the 4 bits:
++ * bit 0 or bit 2 clears the transmit queue and 1 or 3 receive.
++ * writing 1 to all, however, purges cp2108 well enough to avoid the hang.
++ */
++#define PURGE_ALL             0x000f
++
++/*
+  * cp210x_get_config
+  * Reads from the CP210x configuration registers
+  * 'size' is specified in bytes.
+@@ -314,7 +324,7 @@ static int cp210x_get_config(struct usb_serial_port *port, 
u8 request,
+               unsigned int *data, int size)
+ {
+       struct usb_serial *serial = port->serial;
+-      struct cp210x_serial_private *spriv = usb_get_serial_data(serial);
++      struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
+       __le32 *buf;
+       int result, i, length;
+ 
+@@ -330,7 +340,7 @@ static int cp210x_get_config(struct usb_serial_port *port, 
u8 request,
+       /* Issue the request, attempting to read 'size' bytes */
+       result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+                               request, REQTYPE_INTERFACE_TO_HOST, 0x0000,
+-                              spriv->bInterfaceNumber, buf, size,
++                              port_priv->bInterfaceNumber, buf, size,
+                               USB_CTRL_GET_TIMEOUT);
+ 
+       /* Convert data into an array of integers */
+@@ -361,7 +371,7 @@ static int cp210x_set_config(struct usb_serial_port *port, 
u8 request,
+               unsigned int *data, int size)
+ {
+       struct usb_serial *serial = port->serial;
+-      struct cp210x_serial_private *spriv = usb_get_serial_data(serial);
++      struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
+       __le32 *buf;
+       int result, i, length;
+ 
+@@ -382,13 +392,13 @@ static int cp210x_set_config(struct usb_serial_port 
*port, u8 request,
+               result = usb_control_msg(serial->dev,
+                               usb_sndctrlpipe(serial->dev, 0),
+                               request, REQTYPE_HOST_TO_INTERFACE, 0x0000,
+-                              spriv->bInterfaceNumber, buf, size,
++                              port_priv->bInterfaceNumber, buf, size,
+                               USB_CTRL_SET_TIMEOUT);
+       } else {
+               result = usb_control_msg(serial->dev,
+                               usb_sndctrlpipe(serial->dev, 0),
+                               request, REQTYPE_HOST_TO_INTERFACE, data[0],
+-                              spriv->bInterfaceNumber, NULL, 0,
++                              port_priv->bInterfaceNumber, NULL, 0,
+                               USB_CTRL_SET_TIMEOUT);
+       }
+ 
+@@ -418,6 +428,60 @@ static inline int cp210x_set_config_single(struct 
usb_serial_port *port,
+ }
+ 
+ /*
++ * Detect CP2108 GET_LINE_CTL bug and activate workaround.
++ * Write a known good value 0x800, read it back.
++ * If it comes back swapped the bug is detected.
++ * Preserve the original register value.
++ */
++static int cp210x_detect_swapped_line_ctl(struct usb_serial_port *port)
++{
++      struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
++      unsigned int line_ctl_save;
++      unsigned int line_ctl_test;
++      int err;
++
++      err = cp210x_get_config(port, CP210X_GET_LINE_CTL, &line_ctl_save, 2);
++      if (err)
++              return err;
++
++      line_ctl_test = 0x800;
++      err = cp210x_set_config(port, CP210X_SET_LINE_CTL, &line_ctl_test, 2);
++      if (err)
++              return err;
++
++      err = cp210x_get_config(port, CP210X_GET_LINE_CTL, &line_ctl_test, 2);
++      if (err)
++              return err;
++
++      if (line_ctl_test == 8) {
++              port_priv->has_swapped_line_ctl = true;
++              line_ctl_save = swab16((u16)line_ctl_save);
++      }
++
++      return cp210x_set_config(port, CP210X_SET_LINE_CTL, &line_ctl_save, 2);
++}
++
++/*
++ * Must always be called instead of cp210x_get_config(CP210X_GET_LINE_CTL)
++ * to workaround cp2108 bug and get correct value.
++ */
++static int cp210x_get_line_ctl(struct usb_serial_port *port, unsigned int 
*ctl)
++{
++      struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
++      int err;
++
++      err = cp210x_get_config(port, CP210X_GET_LINE_CTL, ctl, 2);
++      if (err)
++              return err;
++
++      /* Workaround swapped bytes in 16-bit value from CP210X_GET_LINE_CTL */
++      if (port_priv->has_swapped_line_ctl)
++              *ctl = swab16((u16)(*ctl));
++
++      return 0;
++}
++
++/*
+  * cp210x_quantise_baudrate
+  * Quantises the baud rate as per AN205 Table 1
+  */
+@@ -482,7 +546,14 @@ static int cp210x_open(struct tty_struct *tty, struct 
usb_serial_port *port)
+ 
+ static void cp210x_close(struct usb_serial_port *port)
+ {
++      unsigned int purge_ctl;
++
+       usb_serial_generic_close(port);
++
++      /* Clear both queues; cp2108 needs this to avoid an occasional hang */
++      purge_ctl = PURGE_ALL;
++      cp210x_set_config(port, CP210X_PURGE, &purge_ctl, 2);
++
+       cp210x_set_config_single(port, CP210X_IFC_ENABLE, UART_DISABLE);
+ }
+ 
+@@ -527,7 +598,7 @@ static void cp210x_get_termios_port(struct usb_serial_port 
*port,
+ 
+       cflag = *cflagp;
+ 
+-      cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2);
++      cp210x_get_line_ctl(port, &bits);
+       cflag &= ~CSIZE;
+       switch (bits & BITS_DATA_MASK) {
+       case BITS_DATA_5:
+@@ -695,7 +766,7 @@ static void cp210x_set_termios(struct tty_struct *tty,
+ 
+       /* If the number of data bits is to be updated */
+       if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
+-              cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2);
++              cp210x_get_line_ctl(port, &bits);
+               bits &= ~BITS_DATA_MASK;
+               switch (cflag & CSIZE) {
+               case CS5:
+@@ -729,7 +800,7 @@ static void cp210x_set_termios(struct tty_struct *tty,
+ 
+       if ((cflag     & (PARENB|PARODD|CMSPAR)) !=
+           (old_cflag & (PARENB|PARODD|CMSPAR))) {
+-              cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2);
++              cp210x_get_line_ctl(port, &bits);
+               bits &= ~BITS_PARITY_MASK;
+               if (cflag & PARENB) {
+                       if (cflag & CMSPAR) {
+@@ -755,7 +826,7 @@ static void cp210x_set_termios(struct tty_struct *tty,
+       }
+ 
+       if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) {
+-              cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2);
++              cp210x_get_line_ctl(port, &bits);
+               bits &= ~BITS_STOP_MASK;
+               if (cflag & CSTOPB) {
+                       bits |= BITS_STOP_2;
+@@ -870,29 +941,39 @@ static void cp210x_break_ctl(struct tty_struct *tty, int 
break_state)
+       cp210x_set_config(port, CP210X_SET_BREAK, &state, 2);
+ }
+ 
+-static int cp210x_startup(struct usb_serial *serial)
++static int cp210x_port_probe(struct usb_serial_port *port)
+ {
++      struct usb_serial *serial = port->serial;
+       struct usb_host_interface *cur_altsetting;
+-      struct cp210x_serial_private *spriv;
++      struct cp210x_port_private *port_priv;
++      int ret;
+ 
+-      spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
+-      if (!spriv)
++      port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL);
++      if (!port_priv)
+               return -ENOMEM;
+ 
+       cur_altsetting = serial->interface->cur_altsetting;
+-      spriv->bInterfaceNumber = cur_altsetting->desc.bInterfaceNumber;
++      port_priv->bInterfaceNumber = cur_altsetting->desc.bInterfaceNumber;
++
++      usb_set_serial_port_data(port, port_priv);
+ 
+-      usb_set_serial_data(serial, spriv);
++      ret = cp210x_detect_swapped_line_ctl(port);
++      if (ret) {
++              kfree(port_priv);
++              return ret;
++      }
+ 
+       return 0;
+ }
+ 
+-static void cp210x_release(struct usb_serial *serial)
++static int cp210x_port_remove(struct usb_serial_port *port)
+ {
+-      struct cp210x_serial_private *spriv;
++      struct cp210x_port_private *port_priv;
++
++      port_priv = usb_get_serial_port_data(port);
++      kfree(port_priv);
+ 
+-      spriv = usb_get_serial_data(serial);
+-      kfree(spriv);
++      return 0;
+ }
+ 
+ module_usb_serial_driver(serial_drivers, id_table);
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index 9bab34cf01d4..24366a2afea6 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -271,6 +271,7 @@ static void option_instat_callback(struct urb *urb);
+ #define TELIT_PRODUCT_UE910_V2                        0x1012
+ #define TELIT_PRODUCT_LE922_USBCFG0           0x1042
+ #define TELIT_PRODUCT_LE922_USBCFG3           0x1043
++#define TELIT_PRODUCT_LE922_USBCFG5           0x1045
+ #define TELIT_PRODUCT_LE920                   0x1200
+ #define TELIT_PRODUCT_LE910                   0x1201
+ 
+@@ -1140,6 +1141,8 @@ static const struct usb_device_id option_ids[] = {
+       { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
+       { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */
+       { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
++      { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9003), /* Quectel UC20 */
++        .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
+       { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003),
+@@ -1191,6 +1194,8 @@ static const struct usb_device_id option_ids[] = {
+               .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG3),
+               .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
++      { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 
TELIT_PRODUCT_LE922_USBCFG5, 0xff),
++              .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910),
+               .driver_info = (kernel_ulong_t)&telit_le910_blacklist },
+       { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920),
+diff --git a/drivers/xen/xen-pciback/pciback_ops.c 
b/drivers/xen/xen-pciback/pciback_ops.c
+index 64eb0cd8b8af..1199d147dcde 100644
+--- a/drivers/xen/xen-pciback/pciback_ops.c
++++ b/drivers/xen/xen-pciback/pciback_ops.c
+@@ -70,6 +70,13 @@ static void xen_pcibk_control_isr(struct pci_dev *dev, int 
reset)
+               enable ? "enable" : "disable");
+ 
+       if (enable) {
++              /*
++               * The MSI or MSI-X should not have an IRQ handler. Otherwise
++               * if the guest terminates we BUG_ON in free_msi_irqs.
++               */
++              if (dev->msi_enabled || dev->msix_enabled)
++                      goto out;
++
+               rc = request_irq(dev_data->irq,
+                               xen_pcibk_guest_interrupt, IRQF_SHARED,
+                               dev_data->irq_name, dev);
+@@ -144,7 +151,12 @@ int xen_pcibk_enable_msi(struct xen_pcibk_device *pdev,
+       if (unlikely(verbose_request))
+               printk(KERN_DEBUG DRV_NAME ": %s: enable MSI\n", pci_name(dev));
+ 
+-      status = pci_enable_msi(dev);
++      if (dev->msi_enabled)
++              status = -EALREADY;
++      else if (dev->msix_enabled)
++              status = -ENXIO;
++      else
++              status = pci_enable_msi(dev);
+ 
+       if (status) {
+               pr_warn_ratelimited("%s: error enabling MSI for guest %u: err 
%d\n",
+@@ -173,20 +185,23 @@ static
+ int xen_pcibk_disable_msi(struct xen_pcibk_device *pdev,
+                         struct pci_dev *dev, struct xen_pci_op *op)
+ {
+-      struct xen_pcibk_dev_data *dev_data;
+-
+       if (unlikely(verbose_request))
+               printk(KERN_DEBUG DRV_NAME ": %s: disable MSI\n",
+                      pci_name(dev));
+-      pci_disable_msi(dev);
+ 
++      if (dev->msi_enabled) {
++              struct xen_pcibk_dev_data *dev_data;
++
++              pci_disable_msi(dev);
++
++              dev_data = pci_get_drvdata(dev);
++              if (dev_data)
++                      dev_data->ack_intr = 1;
++      }
+       op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0;
+       if (unlikely(verbose_request))
+               printk(KERN_DEBUG DRV_NAME ": %s: MSI: %d\n", pci_name(dev),
+                       op->value);
+-      dev_data = pci_get_drvdata(dev);
+-      if (dev_data)
+-              dev_data->ack_intr = 1;
+       return 0;
+ }
+ 
+@@ -197,13 +212,27 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev,
+       struct xen_pcibk_dev_data *dev_data;
+       int i, result;
+       struct msix_entry *entries;
++      u16 cmd;
+ 
+       if (unlikely(verbose_request))
+               printk(KERN_DEBUG DRV_NAME ": %s: enable MSI-X\n",
+                      pci_name(dev));
++
+       if (op->value > SH_INFO_MAX_VEC)
+               return -EINVAL;
+ 
++      if (dev->msix_enabled)
++              return -EALREADY;
++
++      /*
++       * PCI_COMMAND_MEMORY must be enabled, otherwise we may not be able
++       * to access the BARs where the MSI-X entries reside.
++       * But VF devices are unique in which the PF needs to be checked.
++       */
++      pci_read_config_word(pci_physfn(dev), PCI_COMMAND, &cmd);
++      if (dev->msi_enabled || !(cmd & PCI_COMMAND_MEMORY))
++              return -ENXIO;
++
+       entries = kmalloc(op->value * sizeof(*entries), GFP_KERNEL);
+       if (entries == NULL)
+               return -ENOMEM;
+@@ -245,23 +274,27 @@ static
+ int xen_pcibk_disable_msix(struct xen_pcibk_device *pdev,
+                          struct pci_dev *dev, struct xen_pci_op *op)
+ {
+-      struct xen_pcibk_dev_data *dev_data;
+       if (unlikely(verbose_request))
+               printk(KERN_DEBUG DRV_NAME ": %s: disable MSI-X\n",
+                       pci_name(dev));
+-      pci_disable_msix(dev);
+ 
++      if (dev->msix_enabled) {
++              struct xen_pcibk_dev_data *dev_data;
++
++              pci_disable_msix(dev);
++
++              dev_data = pci_get_drvdata(dev);
++              if (dev_data)
++                      dev_data->ack_intr = 1;
++      }
+       /*
+        * SR-IOV devices (which don't have any legacy IRQ) have
+        * an undefined IRQ value of zero.
+        */
+       op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0;
+       if (unlikely(verbose_request))
+-              printk(KERN_DEBUG DRV_NAME ": %s: MSI-X: %d\n", pci_name(dev),
+-                      op->value);
+-      dev_data = pci_get_drvdata(dev);
+-      if (dev_data)
+-              dev_data->ack_intr = 1;
++              printk(KERN_DEBUG DRV_NAME ": %s: MSI-X: %d\n",
++                     pci_name(dev), op->value);
+       return 0;
+ }
+ #endif
+diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
+index ea938a8bf240..f53a6e8204d8 100644
+--- a/fs/cifs/cifssmb.c
++++ b/fs/cifs/cifssmb.c
+@@ -1378,11 +1378,10 @@ openRetry:
+  * current bigbuf.
+  */
+ static int
+-cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
++discard_remaining_data(struct TCP_Server_Info *server)
+ {
+       unsigned int rfclen = get_rfc1002_length(server->smallbuf);
+       int remaining = rfclen + 4 - server->total_read;
+-      struct cifs_readdata *rdata = mid->callback_data;
+ 
+       while (remaining > 0) {
+               int length;
+@@ -1396,10 +1395,20 @@ cifs_readv_discard(struct TCP_Server_Info *server, 
struct mid_q_entry *mid)
+               remaining -= length;
+       }
+ 
+-      dequeue_mid(mid, rdata->result);
+       return 0;
+ }
+ 
++static int
++cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
++{
++      int length;
++      struct cifs_readdata *rdata = mid->callback_data;
++
++      length = discard_remaining_data(server);
++      dequeue_mid(mid, rdata->result);
++      return length;
++}
++
+ int
+ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
+ {
+@@ -1428,6 +1437,12 @@ cifs_readv_receive(struct TCP_Server_Info *server, 
struct mid_q_entry *mid)
+               return length;
+       server->total_read += length;
+ 
++      if (server->ops->is_status_pending &&
++          server->ops->is_status_pending(buf, server, 0)) {
++              discard_remaining_data(server);
++              return -1;
++      }
++
+       /* Was the SMB read successful? */
+       rdata->result = server->ops->map_error(buf, false);
+       if (rdata->result != 0) {
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
+index 1bf0ba805ef5..a47ac835145b 100644
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -1000,21 +1000,25 @@ parse_lease_state(struct TCP_Server_Info *server, 
struct smb2_create_rsp *rsp,
+ {
+       char *data_offset;
+       struct create_context *cc;
+-      unsigned int next = 0;
++      unsigned int next;
++      unsigned int remaining;
+       char *name;
+ 
+       data_offset = (char *)rsp + 4 + le32_to_cpu(rsp->CreateContextsOffset);
++      remaining = le32_to_cpu(rsp->CreateContextsLength);
+       cc = (struct create_context *)data_offset;
+-      do {
+-              cc = (struct create_context *)((char *)cc + next);
++      while (remaining >= sizeof(struct create_context)) {
+               name = le16_to_cpu(cc->NameOffset) + (char *)cc;
+-              if (le16_to_cpu(cc->NameLength) != 4 ||
+-                  strncmp(name, "RqLs", 4)) {
+-                      next = le32_to_cpu(cc->Next);
+-                      continue;
+-              }
+-              return server->ops->parse_lease_buf(cc, epoch);
+-      } while (next != 0);
++              if (le16_to_cpu(cc->NameLength) == 4 &&
++                  strncmp(name, "RqLs", 4) == 0)
++                      return server->ops->parse_lease_buf(cc, epoch);
++
++              next = le32_to_cpu(cc->Next);
++              if (!next)
++                      break;
++              remaining -= next;
++              cc = (struct create_context *)((char *)cc + next);
++      }
+ 
+       return 0;
+ }
+diff --git a/fs/efivarfs/file.c b/fs/efivarfs/file.c
+index 8dd524f32284..08f105a06fbf 100644
+--- a/fs/efivarfs/file.c
++++ b/fs/efivarfs/file.c
+@@ -10,6 +10,7 @@
+ #include <linux/efi.h>
+ #include <linux/fs.h>
+ #include <linux/slab.h>
++#include <linux/mount.h>
+ 
+ #include "internal.h"
+ 
+@@ -108,9 +109,79 @@ out_free:
+       return size;
+ }
+ 
++static int
++efivarfs_ioc_getxflags(struct file *file, void __user *arg)
++{
++      struct inode *inode = file->f_mapping->host;
++      unsigned int i_flags;
++      unsigned int flags = 0;
++
++      i_flags = inode->i_flags;
++      if (i_flags & S_IMMUTABLE)
++              flags |= FS_IMMUTABLE_FL;
++
++      if (copy_to_user(arg, &flags, sizeof(flags)))
++              return -EFAULT;
++      return 0;
++}
++
++static int
++efivarfs_ioc_setxflags(struct file *file, void __user *arg)
++{
++      struct inode *inode = file->f_mapping->host;
++      unsigned int flags;
++      unsigned int i_flags = 0;
++      int error;
++
++      if (!inode_owner_or_capable(inode))
++              return -EACCES;
++
++      if (copy_from_user(&flags, arg, sizeof(flags)))
++              return -EFAULT;
++
++      if (flags & ~FS_IMMUTABLE_FL)
++              return -EOPNOTSUPP;
++
++      if (!capable(CAP_LINUX_IMMUTABLE))
++              return -EPERM;
++
++      if (flags & FS_IMMUTABLE_FL)
++              i_flags |= S_IMMUTABLE;
++
++
++      error = mnt_want_write_file(file);
++      if (error)
++              return error;
++
++      mutex_lock(&inode->i_mutex);
++      inode->i_flags &= ~S_IMMUTABLE;
++      inode->i_flags |= i_flags;
++      mutex_unlock(&inode->i_mutex);
++
++      mnt_drop_write_file(file);
++
++      return 0;
++}
++
++long
++efivarfs_file_ioctl(struct file *file, unsigned int cmd, unsigned long p)
++{
++      void __user *arg = (void __user *)p;
++
++      switch (cmd) {
++      case FS_IOC_GETFLAGS:
++              return efivarfs_ioc_getxflags(file, arg);
++      case FS_IOC_SETFLAGS:
++              return efivarfs_ioc_setxflags(file, arg);
++      }
++
++      return -ENOTTY;
++}
++
+ const struct file_operations efivarfs_file_operations = {
+       .open   = simple_open,
+       .read   = efivarfs_file_read,
+       .write  = efivarfs_file_write,
+       .llseek = no_llseek,
++      .unlocked_ioctl = efivarfs_file_ioctl,
+ };
+diff --git a/fs/efivarfs/inode.c b/fs/efivarfs/inode.c
+index 07ab49745e31..7e7318f10575 100644
+--- a/fs/efivarfs/inode.c
++++ b/fs/efivarfs/inode.c
+@@ -15,7 +15,8 @@
+ #include "internal.h"
+ 
+ struct inode *efivarfs_get_inode(struct super_block *sb,
+-                              const struct inode *dir, int mode, dev_t dev)
++                              const struct inode *dir, int mode,
++                              dev_t dev, bool is_removable)
+ {
+       struct inode *inode = new_inode(sb);
+ 
+@@ -23,6 +24,7 @@ struct inode *efivarfs_get_inode(struct super_block *sb,
+               inode->i_ino = get_next_ino();
+               inode->i_mode = mode;
+               inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
++              inode->i_flags = is_removable ? 0 : S_IMMUTABLE;
+               switch (mode & S_IFMT) {
+               case S_IFREG:
+                       inode->i_fop = &efivarfs_file_operations;
+@@ -102,22 +104,17 @@ static void efivarfs_hex_to_guid(const char *str, 
efi_guid_t *guid)
+ static int efivarfs_create(struct inode *dir, struct dentry *dentry,
+                         umode_t mode, bool excl)
+ {
+-      struct inode *inode;
++      struct inode *inode = NULL;
+       struct efivar_entry *var;
+       int namelen, i = 0, err = 0;
++      bool is_removable = false;
+ 
+       if (!efivarfs_valid_name(dentry->d_name.name, dentry->d_name.len))
+               return -EINVAL;
+ 
+-      inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0);
+-      if (!inode)
+-              return -ENOMEM;
+-
+       var = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL);
+-      if (!var) {
+-              err = -ENOMEM;
+-              goto out;
+-      }
++      if (!var)
++              return -ENOMEM;
+ 
+       /* length of the variable name itself: remove GUID and separator */
+       namelen = dentry->d_name.len - EFI_VARIABLE_GUID_LEN - 1;
+@@ -125,6 +122,16 @@ static int efivarfs_create(struct inode *dir, struct 
dentry *dentry,
+       efivarfs_hex_to_guid(dentry->d_name.name + namelen + 1,
+                       &var->var.VendorGuid);
+ 
++      if (efivar_variable_is_removable(var->var.VendorGuid,
++                                       dentry->d_name.name, namelen))
++              is_removable = true;
++
++      inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0, is_removable);
++      if (!inode) {
++              err = -ENOMEM;
++              goto out;
++      }
++
+       for (i = 0; i < namelen; i++)
+               var->var.VariableName[i] = dentry->d_name.name[i];
+ 
+@@ -138,7 +145,8 @@ static int efivarfs_create(struct inode *dir, struct 
dentry *dentry,
+ out:
+       if (err) {
+               kfree(var);
+-              iput(inode);
++              if (inode)
++                      iput(inode);
+       }
+       return err;
+ }
+diff --git a/fs/efivarfs/internal.h b/fs/efivarfs/internal.h
+index b5ff16addb7c..b4505188e799 100644
+--- a/fs/efivarfs/internal.h
++++ b/fs/efivarfs/internal.h
+@@ -15,7 +15,8 @@ extern const struct file_operations efivarfs_file_operations;
+ extern const struct inode_operations efivarfs_dir_inode_operations;
+ extern bool efivarfs_valid_name(const char *str, int len);
+ extern struct inode *efivarfs_get_inode(struct super_block *sb,
+-                      const struct inode *dir, int mode, dev_t dev);
++                      const struct inode *dir, int mode, dev_t dev,
++                      bool is_removable);
+ 
+ extern struct list_head efivarfs_list;
+ 
+diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
+index a8766b880c07..a2ba231e0b67 100644
+--- a/fs/efivarfs/super.c
++++ b/fs/efivarfs/super.c
+@@ -127,8 +127,9 @@ static int efivarfs_callback(efi_char16_t *name16, 
efi_guid_t vendor,
+       struct dentry *dentry, *root = sb->s_root;
+       unsigned long size = 0;
+       char *name;
+-      int len, i;
++      int len;
+       int err = -ENOMEM;
++      bool is_removable = false;
+ 
+       entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+       if (!entry)
+@@ -137,15 +138,17 @@ static int efivarfs_callback(efi_char16_t *name16, 
efi_guid_t vendor,
+       memcpy(entry->var.VariableName, name16, name_size);
+       memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t));
+ 
+-      len = ucs2_strlen(entry->var.VariableName);
++      len = ucs2_utf8size(entry->var.VariableName);
+ 
+       /* name, plus '-', plus GUID, plus NUL*/
+       name = kmalloc(len + 1 + EFI_VARIABLE_GUID_LEN + 1, GFP_KERNEL);
+       if (!name)
+               goto fail;
+ 
+-      for (i = 0; i < len; i++)
+-              name[i] = entry->var.VariableName[i] & 0xFF;
++      ucs2_as_utf8(name, entry->var.VariableName, len);
++
++      if (efivar_variable_is_removable(entry->var.VendorGuid, name, len))
++              is_removable = true;
+ 
+       name[len] = '-';
+ 
+@@ -153,7 +156,8 @@ static int efivarfs_callback(efi_char16_t *name16, 
efi_guid_t vendor,
+ 
+       name[len + EFI_VARIABLE_GUID_LEN+1] = '\0';
+ 
+-      inode = efivarfs_get_inode(sb, root->d_inode, S_IFREG | 0644, 0);
++      inode = efivarfs_get_inode(sb, root->d_inode, S_IFREG | 0644, 0,
++                                 is_removable);
+       if (!inode)
+               goto fail_name;
+ 
+@@ -209,7 +213,7 @@ static int efivarfs_fill_super(struct super_block *sb, 
void *data, int silent)
+       sb->s_d_op              = &efivarfs_d_ops;
+       sb->s_time_gran         = 1;
+ 
+-      inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0);
++      inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0, true);
+       if (!inode)
+               return -ENOMEM;
+       inode->i_op = &efivarfs_dir_inode_operations;
+diff --git a/fs/jffs2/README.Locking b/fs/jffs2/README.Locking
+index 3ea36554107f..8918ac905a3b 100644
+--- a/fs/jffs2/README.Locking
++++ b/fs/jffs2/README.Locking
+@@ -2,10 +2,6 @@
+       JFFS2 LOCKING DOCUMENTATION
+       ---------------------------
+ 
+-At least theoretically, JFFS2 does not require the Big Kernel Lock
+-(BKL), which was always helpfully obtained for it by Linux 2.4 VFS
+-code. It has its own locking, as described below.
+-
+ This document attempts to describe the existing locking rules for
+ JFFS2. It is not expected to remain perfectly up to date, but ought to
+ be fairly close.
+@@ -69,6 +65,7 @@ Ordering constraints:
+          any f->sem held.
+       2. Never attempt to lock two file mutexes in one thread.
+          No ordering rules have been made for doing so.
++      3. Never lock a page cache page with f->sem held.
+ 
+ 
+       erase_completion_lock spinlock
+diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c
+index a3750f902adc..c1f04947d7dc 100644
+--- a/fs/jffs2/build.c
++++ b/fs/jffs2/build.c
+@@ -49,7 +49,8 @@ next_inode(int *i, struct jffs2_inode_cache *ic, struct 
jffs2_sb_info *c)
+ 
+ 
+ static void jffs2_build_inode_pass1(struct jffs2_sb_info *c,
+-                                  struct jffs2_inode_cache *ic)
++                                  struct jffs2_inode_cache *ic,
++                                  int *dir_hardlinks)
+ {
+       struct jffs2_full_dirent *fd;
+ 
+@@ -68,19 +69,21 @@ static void jffs2_build_inode_pass1(struct jffs2_sb_info 
*c,
+                       dbg_fsbuild("child \"%s\" (ino #%u) of dir ino #%u 
doesn't exist!\n",
+                                 fd->name, fd->ino, ic->ino);
+                       jffs2_mark_node_obsolete(c, fd->raw);
++                      /* Clear the ic/raw union so it doesn't cause problems 
later. */
++                      fd->ic = NULL;
+                       continue;
+               }
+ 
++              /* From this point, fd->raw is no longer used so we can set 
fd->ic */
++              fd->ic = child_ic;
++              child_ic->pino_nlink++;
++              /* If we appear (at this stage) to have hard-linked directories,
++               * set a flag to trigger a scan later */
+               if (fd->type == DT_DIR) {
+-                      if (child_ic->pino_nlink) {
+-                              JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir 
ino #%u appears to be a hard link\n",
+-                                          fd->name, fd->ino, ic->ino);
+-                              /* TODO: What do we do about it? */
+-                      } else {
+-                              child_ic->pino_nlink = ic->ino;
+-                      }
+-              } else
+-                      child_ic->pino_nlink++;
++                      child_ic->flags |= INO_FLAGS_IS_DIR;
++                      if (child_ic->pino_nlink > 1)
++                              *dir_hardlinks = 1;
++              }
+ 
+               dbg_fsbuild("increased nlink for child \"%s\" (ino #%u)\n", 
fd->name, fd->ino);
+               /* Can't free scan_dents so far. We might need them in pass 2 */
+@@ -94,8 +97,7 @@ static void jffs2_build_inode_pass1(struct jffs2_sb_info *c,
+ */
+ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
+ {
+-      int ret;
+-      int i;
++      int ret, i, dir_hardlinks = 0;
+       struct jffs2_inode_cache *ic;
+       struct jffs2_full_dirent *fd;
+       struct jffs2_full_dirent *dead_fds = NULL;
+@@ -119,7 +121,7 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
+       /* Now scan the directory tree, increasing nlink according to every 
dirent found. */
+       for_each_inode(i, c, ic) {
+               if (ic->scan_dents) {
+-                      jffs2_build_inode_pass1(c, ic);
++                      jffs2_build_inode_pass1(c, ic, &dir_hardlinks);
+                       cond_resched();
+               }
+       }
+@@ -155,6 +157,20 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
+       }
+ 
+       dbg_fsbuild("pass 2a complete\n");
++
++      if (dir_hardlinks) {
++              /* If we detected directory hardlinks earlier, *hopefully*
++               * they are gone now because some of the links were from
++               * dead directories which still had some old dirents lying
++               * around and not yet garbage-collected, but which have
++               * been discarded above. So clear the pino_nlink field
++               * in each directory, so that the final scan below can
++               * print appropriate warnings. */
++              for_each_inode(i, c, ic) {
++                      if (ic->flags & INO_FLAGS_IS_DIR)
++                              ic->pino_nlink = 0;
++              }
++      }
+       dbg_fsbuild("freeing temporary data structures\n");
+ 
+       /* Finally, we can scan again and free the dirent structs */
+@@ -162,6 +178,33 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
+               while(ic->scan_dents) {
+                       fd = ic->scan_dents;
+                       ic->scan_dents = fd->next;
++                      /* We do use the pino_nlink field to count nlink of
++                       * directories during fs build, so set it to the
++                       * parent ino# now. Now that there's hopefully only
++                       * one. */
++                      if (fd->type == DT_DIR) {
++                              if (!fd->ic) {
++                                      /* We'll have complained about it and 
marked the coresponding
++                                         raw node obsolete already. Just skip 
it. */
++                                      continue;
++                              }
++
++                              /* We *have* to have set this in 
jffs2_build_inode_pass1() */
++                              BUG_ON(!(fd->ic->flags & INO_FLAGS_IS_DIR));
++
++                              /* We clear ic->pino_nlink ∀ directories' ic 
*only* if dir_hardlinks
++                               * is set. Otherwise, we know this should never 
trigger anyway, so
++                               * we don't do the check. And ic->pino_nlink 
still contains the nlink
++                               * value (which is 1). */
++                              if (dir_hardlinks && fd->ic->pino_nlink) {
++                                      JFFS2_ERROR("child dir \"%s\" (ino #%u) 
of dir ino #%u is also hard linked from dir ino #%u\n",
++                                                  fd->name, fd->ino, ic->ino, 
fd->ic->pino_nlink);
++                                      /* Should we unlink it from its 
previous parent? */
++                              }
++
++                              /* For directories, ic->pino_nlink holds that 
parent inode # */
++                              fd->ic->pino_nlink = ic->ino;
++                      }
+                       jffs2_free_full_dirent(fd);
+               }
+               ic->scan_dents = NULL;
+@@ -240,11 +283,7 @@ static void jffs2_build_remove_unlinked_inode(struct 
jffs2_sb_info *c,
+ 
+                       /* Reduce nlink of the child. If it's now zero, stick 
it on the
+                          dead_fds list to be cleaned up later. Else just free 
the fd */
+-
+-                      if (fd->type == DT_DIR)
+-                              child_ic->pino_nlink = 0;
+-                      else
+-                              child_ic->pino_nlink--;
++                      child_ic->pino_nlink--;
+ 
+                       if (!child_ic->pino_nlink) {
+                               dbg_fsbuild("inode #%u (\"%s\") now has no 
links; adding to dead_fds list.\n",
+diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
+index 1506673c087e..60ef3fb707ff 100644
+--- a/fs/jffs2/file.c
++++ b/fs/jffs2/file.c
+@@ -138,39 +138,33 @@ static int jffs2_write_begin(struct file *filp, struct 
address_space *mapping,
+       struct page *pg;
+       struct inode *inode = mapping->host;
+       struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
+-      struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+-      struct jffs2_raw_inode ri;
+-      uint32_t alloc_len = 0;
+       pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+       uint32_t pageofs = index << PAGE_CACHE_SHIFT;
+       int ret = 0;
+ 
+-      jffs2_dbg(1, "%s()\n", __func__);
+-
+-      if (pageofs > inode->i_size) {
+-              ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
+-                                        ALLOC_NORMAL, 
JFFS2_SUMMARY_INODE_SIZE);
+-              if (ret)
+-                      return ret;
+-      }
+-
+-      mutex_lock(&f->sem);
+       pg = grab_cache_page_write_begin(mapping, index, flags);
+-      if (!pg) {
+-              if (alloc_len)
+-                      jffs2_complete_reservation(c);
+-              mutex_unlock(&f->sem);
++      if (!pg)
+               return -ENOMEM;
+-      }
+       *pagep = pg;
+ 
+-      if (alloc_len) {
++      jffs2_dbg(1, "%s()\n", __func__);
++
++      if (pageofs > inode->i_size) {
+               /* Make new hole frag from old EOF to new page */
++              struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
++              struct jffs2_raw_inode ri;
+               struct jffs2_full_dnode *fn;
++              uint32_t alloc_len;
+ 
+               jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current 
EOF and new page\n",
+                         (unsigned int)inode->i_size, pageofs);
+ 
++              ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
++                                        ALLOC_NORMAL, 
JFFS2_SUMMARY_INODE_SIZE);
++              if (ret)
++                      goto out_page;
++
++              mutex_lock(&f->sem);
+               memset(&ri, 0, sizeof(ri));
+ 
+               ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
+@@ -197,6 +191,7 @@ static int jffs2_write_begin(struct file *filp, struct 
address_space *mapping,
+               if (IS_ERR(fn)) {
+                       ret = PTR_ERR(fn);
+                       jffs2_complete_reservation(c);
++                      mutex_unlock(&f->sem);
+                       goto out_page;
+               }
+               ret = jffs2_add_full_dnode_to_inode(c, f, fn);
+@@ -211,10 +206,12 @@ static int jffs2_write_begin(struct file *filp, struct 
address_space *mapping,
+                       jffs2_mark_node_obsolete(c, fn->raw);
+                       jffs2_free_full_dnode(fn);
+                       jffs2_complete_reservation(c);
++                      mutex_unlock(&f->sem);
+                       goto out_page;
+               }
+               jffs2_complete_reservation(c);
+               inode->i_size = pageofs;
++              mutex_unlock(&f->sem);
+       }
+ 
+       /*
+@@ -223,18 +220,18 @@ static int jffs2_write_begin(struct file *filp, struct 
address_space *mapping,
+        * case of a short-copy.
+        */
+       if (!PageUptodate(pg)) {
++              mutex_lock(&f->sem);
+               ret = jffs2_do_readpage_nolock(inode, pg);
++              mutex_unlock(&f->sem);
+               if (ret)
+                       goto out_page;
+       }
+-      mutex_unlock(&f->sem);
+       jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags);
+       return ret;
+ 
+ out_page:
+       unlock_page(pg);
+       page_cache_release(pg);
+-      mutex_unlock(&f->sem);
+       return ret;
+ }
+ 
+diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
+index 5a2dec2b064c..95d5880a63ee 100644
+--- a/fs/jffs2/gc.c
++++ b/fs/jffs2/gc.c
+@@ -1296,14 +1296,17 @@ static int jffs2_garbage_collect_dnode(struct 
jffs2_sb_info *c, struct jffs2_era
+               BUG_ON(start > orig_start);
+       }
+ 
+-      /* First, use readpage() to read the appropriate page into the page 
cache */
+-      /* Q: What happens if we actually try to GC the _same_ page for which 
commit_write()
+-       *    triggered garbage collection in the first place?
+-       * A: I _think_ it's OK. read_cache_page shouldn't deadlock, we'll 
write out the
+-       *    page OK. We'll actually write it out again in commit_write, which 
is a little
+-       *    suboptimal, but at least we're correct.
+-       */
++      /* The rules state that we must obtain the page lock *before* f->sem, so
++       * drop f->sem temporarily. Since we also hold c->alloc_sem, nothing's
++       * actually going to *change* so we're safe; we only allow reading.
++       *
++       * It is important to note that jffs2_write_begin() will ensure that its
++       * page is marked Uptodate before allocating space. That means that if 
we
++       * end up here trying to GC the *same* page that jffs2_write_begin() is
++       * trying to write out, read_cache_page() will not deadlock. */
++      mutex_unlock(&f->sem);
+       pg_ptr = jffs2_gc_fetch_page(c, f, start, &pg);
++      mutex_lock(&f->sem);
+ 
+       if (IS_ERR(pg_ptr)) {
+               pr_warn("read_cache_page() returned error: %ld\n",
+diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
+index fa35ff79ab35..0637271f3770 100644
+--- a/fs/jffs2/nodelist.h
++++ b/fs/jffs2/nodelist.h
+@@ -194,6 +194,7 @@ struct jffs2_inode_cache {
+ #define INO_STATE_CLEARING    6       /* In clear_inode() */
+ 
+ #define INO_FLAGS_XATTR_CHECKED       0x01    /* has no duplicate xattr_ref */
++#define INO_FLAGS_IS_DIR      0x02    /* is a directory */
+ 
+ #define RAWNODE_CLASS_INODE_CACHE     0
+ #define RAWNODE_CLASS_XATTR_DATUM     1
+@@ -249,7 +250,10 @@ struct jffs2_readinode_info
+ 
+ struct jffs2_full_dirent
+ {
+-      struct jffs2_raw_node_ref *raw;
++      union {
++              struct jffs2_raw_node_ref *raw;
++              struct jffs2_inode_cache *ic; /* Just during part of build */
++      };
+       struct jffs2_full_dirent *next;
+       uint32_t version;
+       uint32_t ino; /* == zero for unlink */
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index fafac65804d6..e5f146c7c871 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -510,7 +510,7 @@ set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl 
*pacl, char *key)
+       int error = 0;
+ 
+       if (!pacl)
+-              return vfs_setxattr(dentry, key, NULL, 0, 0);
++              return vfs_removexattr(dentry, key);
+ 
+       buflen = posix_acl_xattr_size(pacl->a_count);
+       buf = kmalloc(buflen, GFP_KERNEL);
+diff --git a/include/linux/ata.h b/include/linux/ata.h
+index bf4c69ca76df..72588a69b916 100644
+--- a/include/linux/ata.h
++++ b/include/linux/ata.h
+@@ -477,8 +477,8 @@ enum ata_tf_protocols {
+ };
+ 
+ enum ata_ioctls {
+-      ATA_IOC_GET_IO32        = 0x309,
+-      ATA_IOC_SET_IO32        = 0x324,
++      ATA_IOC_GET_IO32        = 0x309, /* HDIO_GET_32BIT */
++      ATA_IOC_SET_IO32        = 0x324, /* HDIO_SET_32BIT */
+ };
+ 
+ /* core structures */
+diff --git a/include/linux/efi.h b/include/linux/efi.h
+index 094ddd0f5d1c..f38969a074ff 100644
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -769,8 +769,10 @@ struct efivars {
+  * and we use a page for reading/writing.
+  */
+ 
++#define EFI_VAR_NAME_LEN      1024
++
+ struct efi_variable {
+-      efi_char16_t  VariableName[1024/sizeof(efi_char16_t)];
++      efi_char16_t  VariableName[EFI_VAR_NAME_LEN/sizeof(efi_char16_t)];
+       efi_guid_t    VendorGuid;
+       unsigned long DataSize;
+       __u8          Data[1024];
+@@ -834,7 +836,10 @@ int efivar_entry_iter(int (*func)(struct efivar_entry *, 
void *),
+ struct efivar_entry *efivar_entry_find(efi_char16_t *name, efi_guid_t guid,
+                                      struct list_head *head, bool remove);
+ 
+-bool efivar_validate(struct efi_variable *var, u8 *data, unsigned long len);
++bool efivar_validate(efi_guid_t vendor, efi_char16_t *var_name, u8 *data,
++                   unsigned long data_size);
++bool efivar_variable_is_removable(efi_guid_t vendor, const char *name,
++                                size_t len);
+ 
+ extern struct work_struct efivar_work;
+ void efivar_run_worker(void);
+diff --git a/include/linux/libata.h b/include/linux/libata.h
+index 189c9ff97b29..a445209be917 100644
+--- a/include/linux/libata.h
++++ b/include/linux/libata.h
+@@ -712,7 +712,7 @@ struct ata_device {
+       union {
+               u16             id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
+               u32             gscr[SATA_PMP_GSCR_DWORDS]; /* PMP GSCR block */
+-      };
++      } ____cacheline_aligned;
+ 
+       /* DEVSLP Timing Variables from Identify Device Data Log */
+       u8                      devslp_timing[ATA_LOG_DEVSLP_SIZE];
+diff --git a/include/linux/module.h b/include/linux/module.h
+index 73c8c06c25bf..842ef3877d5b 100644
+--- a/include/linux/module.h
++++ b/include/linux/module.h
+@@ -223,6 +223,12 @@ struct module_ref {
+       unsigned long decs;
+ } __attribute((aligned(2 * sizeof(unsigned long))));
+ 
++struct mod_kallsyms {
++      Elf_Sym *symtab;
++      unsigned int num_symtab;
++      char *strtab;
++};
++
+ struct module
+ {
+       enum module_state state;
+@@ -311,14 +317,9 @@ struct module
+ #endif
+ 
+ #ifdef CONFIG_KALLSYMS
+-      /*
+-       * We keep the symbol and string tables for kallsyms.
+-       * The core_* fields below are temporary, loader-only (they
+-       * could really be discarded after module init).
+-       */
+-      Elf_Sym *symtab, *core_symtab;
+-      unsigned int num_symtab, core_num_syms;
+-      char *strtab, *core_strtab;
++      /* Protected by RCU and/or module_mutex: use rcu_dereference() */
++      struct mod_kallsyms *kallsyms;
++      struct mod_kallsyms core_kallsyms;
+ 
+       /* Section attributes */
+       struct module_sect_attrs *sect_attrs;
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index a4d7d19fc338..3ecea51ea060 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -664,6 +664,7 @@ struct user_struct {
+       unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */
+ #endif
+       unsigned long locked_shm; /* How many pages of mlocked shm ? */
++      unsigned long unix_inflight;    /* How many files in flight in unix 
sockets */
+ 
+ #ifdef CONFIG_KEYS
+       struct key *uid_keyring;        /* UID specific keyring */
+diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
+index c1248996006f..9ff9ca22cfb7 100644
+--- a/include/linux/tracepoint.h
++++ b/include/linux/tracepoint.h
+@@ -129,9 +129,6 @@ static inline void tracepoint_synchronize_unregister(void)
+               void *it_func;                                          \
+               void *__data;                                           \
+                                                                       \
+-              if (!cpu_online(raw_smp_processor_id()))                \
+-                      return;                                         \
+-                                                                      \
+               if (!(cond))                                            \
+                       return;                                         \
+               prercu;                                                 \
+@@ -265,15 +262,19 @@ static inline void 
tracepoint_synchronize_unregister(void)
+  * "void *__data, proto" as the callback prototype.
+  */
+ #define DECLARE_TRACE_NOARGS(name)                                    \
+-              __DECLARE_TRACE(name, void, , 1, void *__data, __data)
++      __DECLARE_TRACE(name, void, ,                                   \
++                      cpu_online(raw_smp_processor_id()),             \
++                      void *__data, __data)
+ 
+ #define DECLARE_TRACE(name, proto, args)                              \
+-              __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), 1,   \
+-                              PARAMS(void *__data, proto),            \
+-                              PARAMS(__data, args))
++      __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),              \
++                      cpu_online(raw_smp_processor_id()),             \
++                      PARAMS(void *__data, proto),                    \
++                      PARAMS(__data, args))
+ 
+ #define DECLARE_TRACE_CONDITION(name, proto, args, cond)              \
+-      __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), PARAMS(cond), \
++      __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args),              \
++                      cpu_online(raw_smp_processor_id()) && (PARAMS(cond)), \
+                       PARAMS(void *__data, proto),                    \
+                       PARAMS(__data, args))
+ 
+diff --git a/include/linux/ucs2_string.h b/include/linux/ucs2_string.h
+index cbb20afdbc01..bb679b48f408 100644
+--- a/include/linux/ucs2_string.h
++++ b/include/linux/ucs2_string.h
+@@ -11,4 +11,8 @@ unsigned long ucs2_strlen(const ucs2_char_t *s);
+ unsigned long ucs2_strsize(const ucs2_char_t *data, unsigned long maxlength);
+ int ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, size_t len);
+ 
++unsigned long ucs2_utf8size(const ucs2_char_t *src);
++unsigned long ucs2_as_utf8(u8 *dest, const ucs2_char_t *src,
++                         unsigned long maxlength);
++
+ #endif /* _LINUX_UCS2_STRING_H_ */
+diff --git a/include/net/af_unix.h b/include/net/af_unix.h
+index e830c3dff61a..7bb69c9c3c43 100644
+--- a/include/net/af_unix.h
++++ b/include/net/af_unix.h
+@@ -6,8 +6,8 @@
+ #include <linux/mutex.h>
+ #include <net/sock.h>
+ 
+-void unix_inflight(struct file *fp);
+-void unix_notinflight(struct file *fp);
++void unix_inflight(struct user_struct *user, struct file *fp);
++void unix_notinflight(struct user_struct *user, struct file *fp);
+ void unix_gc(void);
+ void wait_for_unix_gc(void);
+ struct sock *unix_get_socket(struct file *filp);
+diff --git a/include/net/scm.h b/include/net/scm.h
+index 8de2d37d2077..d00cd43a990c 100644
+--- a/include/net/scm.h
++++ b/include/net/scm.h
+@@ -21,6 +21,7 @@ struct scm_creds {
+ struct scm_fp_list {
+       short                   count;
+       short                   max;
++      struct user_struct      *user;
+       struct file             *fp[SCM_MAX_FD];
+ };
+ 
+diff --git a/kernel/module.c b/kernel/module.c
+index cb56e581062d..ec40f03aa473 100644
+--- a/kernel/module.c
++++ b/kernel/module.c
+@@ -180,6 +180,9 @@ struct load_info {
+       struct _ddebug *debug;
+       unsigned int num_debug;
+       bool sig_ok;
++#ifdef CONFIG_KALLSYMS
++      unsigned long mod_kallsyms_init_off;
++#endif
+       struct {
+               unsigned int sym, str, mod, vers, info, pcpu;
+       } index;
+@@ -2362,8 +2365,20 @@ static void layout_symtab(struct module *mod, struct 
load_info *info)
+       strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect,
+                                        info->index.str) | INIT_OFFSET_MASK;
+       pr_debug("\t%s\n", info->secstrings + strsect->sh_name);
++
++      /* We'll tack temporary mod_kallsyms on the end. */
++      mod->init_size = ALIGN(mod->init_size,
++                             __alignof__(struct mod_kallsyms));
++      info->mod_kallsyms_init_off = mod->init_size;
++      mod->init_size += sizeof(struct mod_kallsyms);
++      mod->init_size = debug_align(mod->init_size);
+ }
+ 
++/*
++ * We use the full symtab and strtab which layout_symtab arranged to
++ * be appended to the init section.  Later we switch to the cut-down
++ * core-only ones.
++ */
+ static void add_kallsyms(struct module *mod, const struct load_info *info)
+ {
+       unsigned int i, ndst;
+@@ -2372,28 +2387,33 @@ static void add_kallsyms(struct module *mod, const 
struct load_info *info)
+       char *s;
+       Elf_Shdr *symsec = &info->sechdrs[info->index.sym];
+ 
+-      mod->symtab = (void *)symsec->sh_addr;
+-      mod->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
++      /* Set up to point into init section. */
++      mod->kallsyms = mod->module_init + info->mod_kallsyms_init_off;
++
++      mod->kallsyms->symtab = (void *)symsec->sh_addr;
++      mod->kallsyms->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
+       /* Make sure we get permanent strtab: don't use info->strtab. */
+-      mod->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
++      mod->kallsyms->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
+ 
+       /* Set types up while we still have access to sections. */
+-      for (i = 0; i < mod->num_symtab; i++)
+-              mod->symtab[i].st_info = elf_type(&mod->symtab[i], info);
+-
+-      mod->core_symtab = dst = mod->module_core + info->symoffs;
+-      mod->core_strtab = s = mod->module_core + info->stroffs;
+-      src = mod->symtab;
+-      for (ndst = i = 0; i < mod->num_symtab; i++) {
++      for (i = 0; i < mod->kallsyms->num_symtab; i++)
++              mod->kallsyms->symtab[i].st_info
++                      = elf_type(&mod->kallsyms->symtab[i], info);
++
++      /* Now populate the cut down core kallsyms for after init. */
++      mod->core_kallsyms.symtab = dst = mod->module_core + info->symoffs;
++      mod->core_kallsyms.strtab = s = mod->module_core + info->stroffs;
++      src = mod->kallsyms->symtab;
++      for (ndst = i = 0; i < mod->kallsyms->num_symtab; i++) {
+               if (i == 0 ||
+                   is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
+                       dst[ndst] = src[i];
+-                      dst[ndst++].st_name = s - mod->core_strtab;
+-                      s += strlcpy(s, &mod->strtab[src[i].st_name],
++                      dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
++                      s += strlcpy(s, &mod->kallsyms->strtab[src[i].st_name],
+                                    KSYM_NAME_LEN) + 1;
+               }
+       }
+-      mod->core_num_syms = ndst;
++      mod->core_kallsyms.num_symtab = ndst;
+ }
+ #else
+ static inline void layout_symtab(struct module *mod, struct load_info *info)
+@@ -3107,9 +3127,8 @@ static int do_init_module(struct module *mod)
+       module_put(mod);
+       trim_init_extable(mod);
+ #ifdef CONFIG_KALLSYMS
+-      mod->num_symtab = mod->core_num_syms;
+-      mod->symtab = mod->core_symtab;
+-      mod->strtab = mod->core_strtab;
++      /* Switch to core kallsyms now init is done: kallsyms may be walking! */
++      rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms);
+ #endif
+       unset_module_init_ro_nx(mod);
+       module_free(mod, mod->module_init);
+@@ -3425,9 +3444,9 @@ static inline int is_arm_mapping_symbol(const char *str)
+              && (str[2] == '\0' || str[2] == '.');
+ }
+ 
+-static const char *symname(struct module *mod, unsigned int symnum)
++static const char *symname(struct mod_kallsyms *kallsyms, unsigned int symnum)
+ {
+-      return mod->strtab + mod->symtab[symnum].st_name;
++      return kallsyms->strtab + kallsyms->symtab[symnum].st_name;
+ }
+ 
+ static const char *get_ksymbol(struct module *mod,
+@@ -3437,6 +3456,7 @@ static const char *get_ksymbol(struct module *mod,
+ {
+       unsigned int i, best = 0;
+       unsigned long nextval;
++      struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
+ 
+       /* At worse, next value is at end of module */
+       if (within_module_init(addr, mod))
+@@ -3446,32 +3466,32 @@ static const char *get_ksymbol(struct module *mod,
+ 
+       /* Scan for closest preceding symbol, and next symbol. (ELF
+          starts real symbols at 1). */
+-      for (i = 1; i < mod->num_symtab; i++) {
+-              if (mod->symtab[i].st_shndx == SHN_UNDEF)
++      for (i = 1; i < kallsyms->num_symtab; i++) {
++              if (kallsyms->symtab[i].st_shndx == SHN_UNDEF)
+                       continue;
+ 
+               /* We ignore unnamed symbols: they're uninformative
+                * and inserted at a whim. */
+-              if (*symname(mod, i) == '\0'
+-                  || is_arm_mapping_symbol(symname(mod, i)))
++              if (*symname(kallsyms, i) == '\0'
++                  || is_arm_mapping_symbol(symname(kallsyms, i)))
+                       continue;
+ 
+-              if (mod->symtab[i].st_value <= addr
+-                  && mod->symtab[i].st_value > mod->symtab[best].st_value)
++              if (kallsyms->symtab[i].st_value <= addr
++                  && kallsyms->symtab[i].st_value > 
kallsyms->symtab[best].st_value)
+                       best = i;
+-              if (mod->symtab[i].st_value > addr
+-                  && mod->symtab[i].st_value < nextval)
+-                      nextval = mod->symtab[i].st_value;
++              if (kallsyms->symtab[i].st_value > addr
++                  && kallsyms->symtab[i].st_value < nextval)
++                      nextval = kallsyms->symtab[i].st_value;
+       }
+ 
+       if (!best)
+               return NULL;
+ 
+       if (size)
+-              *size = nextval - mod->symtab[best].st_value;
++              *size = nextval - kallsyms->symtab[best].st_value;
+       if (offset)
+-              *offset = addr - mod->symtab[best].st_value;
+-      return symname(mod, best);
++              *offset = addr - kallsyms->symtab[best].st_value;
++      return symname(kallsyms, best);
+ }
+ 
+ /* For kallsyms to ask for address resolution.  NULL means not found.  Careful
+@@ -3567,18 +3587,21 @@ int module_get_kallsym(unsigned int symnum, unsigned 
long *value, char *type,
+ 
+       preempt_disable();
+       list_for_each_entry_rcu(mod, &modules, list) {
++              struct mod_kallsyms *kallsyms;
++
+               if (mod->state == MODULE_STATE_UNFORMED)
+                       continue;
+-              if (symnum < mod->num_symtab) {
+-                      *value = mod->symtab[symnum].st_value;
+-                      *type = mod->symtab[symnum].st_info;
+-                      strlcpy(name, symname(mod, symnum), KSYM_NAME_LEN);
++              kallsyms = rcu_dereference_sched(mod->kallsyms);
++              if (symnum < kallsyms->num_symtab) {
++                      *value = kallsyms->symtab[symnum].st_value;
++                      *type = kallsyms->symtab[symnum].st_info;
++                      strlcpy(name, symname(kallsyms, symnum), KSYM_NAME_LEN);
+                       strlcpy(module_name, mod->name, MODULE_NAME_LEN);
+                       *exported = is_exported(name, *value, mod);
+                       preempt_enable();
+                       return 0;
+               }
+-              symnum -= mod->num_symtab;
++              symnum -= kallsyms->num_symtab;
+       }
+       preempt_enable();
+       return -ERANGE;
+@@ -3587,11 +3610,12 @@ int module_get_kallsym(unsigned int symnum, unsigned 
long *value, char *type,
+ static unsigned long mod_find_symname(struct module *mod, const char *name)
+ {
+       unsigned int i;
++      struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
+ 
+-      for (i = 0; i < mod->num_symtab; i++)
+-              if (strcmp(name, symname(mod, i)) == 0 &&
+-                  mod->symtab[i].st_info != 'U')
+-                      return mod->symtab[i].st_value;
++      for (i = 0; i < kallsyms->num_symtab; i++)
++              if (strcmp(name, symname(kallsyms, i)) == 0 &&
++                  kallsyms->symtab[i].st_info != 'U')
++                      return kallsyms->symtab[i].st_value;
+       return 0;
+ }
+ 
+@@ -3628,11 +3652,14 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, 
const char *,
+       int ret;
+ 
+       list_for_each_entry(mod, &modules, list) {
++              /* We hold module_mutex: no need for rcu_dereference_sched */
++              struct mod_kallsyms *kallsyms = mod->kallsyms;
++
+               if (mod->state == MODULE_STATE_UNFORMED)
+                       continue;
+-              for (i = 0; i < mod->num_symtab; i++) {
+-                      ret = fn(data, symname(mod, i),
+-                               mod, mod->symtab[i].st_value);
++              for (i = 0; i < kallsyms->num_symtab; i++) {
++                      ret = fn(data, symname(kallsyms, i),
++                               mod, kallsyms->symtab[i].st_value);
+                       if (ret != 0)
+                               return ret;
+               }
+diff --git a/lib/ucs2_string.c b/lib/ucs2_string.c
+index 6f500ef2301d..f0b323abb4c6 100644
+--- a/lib/ucs2_string.c
++++ b/lib/ucs2_string.c
+@@ -49,3 +49,65 @@ ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, 
size_t len)
+         }
+ }
+ EXPORT_SYMBOL(ucs2_strncmp);
++
++unsigned long
++ucs2_utf8size(const ucs2_char_t *src)
++{
++      unsigned long i;
++      unsigned long j = 0;
++
++      for (i = 0; i < ucs2_strlen(src); i++) {
++              u16 c = src[i];
++
++              if (c >= 0x800)
++                      j += 3;
++              else if (c >= 0x80)
++                      j += 2;
++              else
++                      j += 1;
++      }
++
++      return j;
++}
++EXPORT_SYMBOL(ucs2_utf8size);
++
++/*
++ * copy at most maxlength bytes of whole utf8 characters to dest from the
++ * ucs2 string src.
++ *
++ * The return value is the number of characters copied, not including the
++ * final NUL character.
++ */
++unsigned long
++ucs2_as_utf8(u8 *dest, const ucs2_char_t *src, unsigned long maxlength)
++{
++      unsigned int i;
++      unsigned long j = 0;
++      unsigned long limit = ucs2_strnlen(src, maxlength);
++
++      for (i = 0; maxlength && i < limit; i++) {
++              u16 c = src[i];
++
++              if (c >= 0x800) {
++                      if (maxlength < 3)
++                              break;
++                      maxlength -= 3;
++                      dest[j++] = 0xe0 | (c & 0xf000) >> 12;
++                      dest[j++] = 0x80 | (c & 0x0fc0) >> 6;
++                      dest[j++] = 0x80 | (c & 0x003f);
++              } else if (c >= 0x80) {
++                      if (maxlength < 2)
++                              break;
++                      maxlength -= 2;
++                      dest[j++] = 0xc0 | (c & 0x7c0) >> 6;
++                      dest[j++] = 0x80 | (c & 0x03f);
++              } else {
++                      maxlength -= 1;
++                      dest[j++] = c & 0x7f;
++              }
++      }
++      if (maxlength)
++              dest[j] = '\0';
++      return j;
++}
++EXPORT_SYMBOL(ucs2_as_utf8);
+diff --git a/net/core/scm.c b/net/core/scm.c
+index d30eb057fa7b..cad57a1390dd 100644
+--- a/net/core/scm.c
++++ b/net/core/scm.c
+@@ -87,6 +87,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct 
scm_fp_list **fplp)
+               *fplp = fpl;
+               fpl->count = 0;
+               fpl->max = SCM_MAX_FD;
++              fpl->user = NULL;
+       }
+       fpp = &fpl->fp[fpl->count];
+ 
+@@ -107,6 +108,10 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct 
scm_fp_list **fplp)
+               *fpp++ = file;
+               fpl->count++;
+       }
++
++      if (!fpl->user)
++              fpl->user = get_uid(current_user());
++
+       return num;
+ }
+ 
+@@ -119,6 +124,7 @@ void __scm_destroy(struct scm_cookie *scm)
+               scm->fp = NULL;
+               for (i=fpl->count-1; i>=0; i--)
+                       fput(fpl->fp[i]);
++              free_uid(fpl->user);
+               kfree(fpl);
+       }
+ }
+@@ -337,6 +343,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
+               for (i = 0; i < fpl->count; i++)
+                       get_file(fpl->fp[i]);
+               new_fpl->max = new_fpl->count;
++              new_fpl->user = get_uid(fpl->user);
+       }
+       return new_fpl;
+ }
+diff --git a/net/mac80211/rc80211_minstrel_ht.c 
b/net/mac80211/rc80211_minstrel_ht.c
+index 7c323f27ba23..96b6dc0155de 100644
+--- a/net/mac80211/rc80211_minstrel_ht.c
++++ b/net/mac80211/rc80211_minstrel_ht.c
+@@ -454,7 +454,7 @@ minstrel_aggr_check(struct ieee80211_sta *pubsta, struct 
sk_buff *skb)
+       if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO)
+               return;
+ 
+-      ieee80211_start_tx_ba_session(pubsta, tid, 5000);
++      ieee80211_start_tx_ba_session(pubsta, tid, 0);
+ }
+ 
+ static void
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index c5536b7d8ce4..3974413f78e7 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -1467,7 +1467,7 @@ static void unix_detach_fds(struct scm_cookie *scm, 
struct sk_buff *skb)
+       UNIXCB(skb).fp = NULL;
+ 
+       for (i = scm->fp->count-1; i >= 0; i--)
+-              unix_notinflight(scm->fp->fp[i]);
++              unix_notinflight(scm->fp->user, scm->fp->fp[i]);
+ }
+ 
+ static void unix_destruct_scm(struct sk_buff *skb)
+@@ -1484,6 +1484,21 @@ static void unix_destruct_scm(struct sk_buff *skb)
+       sock_wfree(skb);
+ }
+ 
++/*
++ * The "user->unix_inflight" variable is protected by the garbage
++ * collection lock, and we just read it locklessly here. If you go
++ * over the limit, there might be a tiny race in actually noticing
++ * it across threads. Tough.
++ */
++static inline bool too_many_unix_fds(struct task_struct *p)
++{
++      struct user_struct *user = current_user();
++
++      if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE)))
++              return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
++      return false;
++}
++
+ #define MAX_RECURSION_LEVEL 4
+ 
+ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
+@@ -1492,6 +1507,9 @@ static int unix_attach_fds(struct scm_cookie *scm, 
struct sk_buff *skb)
+       unsigned char max_level = 0;
+       int unix_sock_count = 0;
+ 
++      if (too_many_unix_fds(current))
++              return -ETOOMANYREFS;
++
+       for (i = scm->fp->count - 1; i >= 0; i--) {
+               struct sock *sk = unix_get_socket(scm->fp->fp[i]);
+ 
+@@ -1513,10 +1531,8 @@ static int unix_attach_fds(struct scm_cookie *scm, 
struct sk_buff *skb)
+       if (!UNIXCB(skb).fp)
+               return -ENOMEM;
+ 
+-      if (unix_sock_count) {
+-              for (i = scm->fp->count - 1; i >= 0; i--)
+-                      unix_inflight(scm->fp->fp[i]);
+-      }
++      for (i = scm->fp->count - 1; i >= 0; i--)
++              unix_inflight(scm->fp->user, scm->fp->fp[i]);
+       return max_level;
+ }
+ 
+diff --git a/net/unix/garbage.c b/net/unix/garbage.c
+index 9bc73f87f64a..a72182d6750f 100644
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -122,12 +122,15 @@ struct sock *unix_get_socket(struct file *filp)
+  *    descriptor if it is for an AF_UNIX socket.
+  */
+ 
+-void unix_inflight(struct file *fp)
++void unix_inflight(struct user_struct *user, struct file *fp)
+ {
+       struct sock *s = unix_get_socket(fp);
++
++      spin_lock(&unix_gc_lock);
++
+       if (s) {
+               struct unix_sock *u = unix_sk(s);
+-              spin_lock(&unix_gc_lock);
++
+               if (atomic_long_inc_return(&u->inflight) == 1) {
+                       BUG_ON(!list_empty(&u->link));
+                       list_add_tail(&u->link, &gc_inflight_list);
+@@ -135,22 +138,27 @@ void unix_inflight(struct file *fp)
+                       BUG_ON(list_empty(&u->link));
+               }
+               unix_tot_inflight++;
+-              spin_unlock(&unix_gc_lock);
+       }
++      user->unix_inflight++;
++      spin_unlock(&unix_gc_lock);
+ }
+ 
+-void unix_notinflight(struct file *fp)
++void unix_notinflight(struct user_struct *user, struct file *fp)
+ {
+       struct sock *s = unix_get_socket(fp);
++
++      spin_lock(&unix_gc_lock);
++
+       if (s) {
+               struct unix_sock *u = unix_sk(s);
+-              spin_lock(&unix_gc_lock);
++
+               BUG_ON(list_empty(&u->link));
+               if (atomic_long_dec_and_test(&u->inflight))
+                       list_del_init(&u->link);
+               unix_tot_inflight--;
+-              spin_unlock(&unix_gc_lock);
+       }
++      user->unix_inflight--;
++      spin_unlock(&unix_gc_lock);
+ }
+ 
+ static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
+diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
+index c8717c1d082e..87dd619fb2e9 100644
+--- a/net/wireless/wext-core.c
++++ b/net/wireless/wext-core.c
+@@ -342,6 +342,39 @@ static const int compat_event_type_size[] = {
+ 
+ /* IW event code */
+ 
++static void wireless_nlevent_flush(void)
++{
++      struct sk_buff *skb;
++      struct net *net;
++
++      ASSERT_RTNL();
++
++      for_each_net(net) {
++              while ((skb = skb_dequeue(&net->wext_nlevents)))
++                      rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL,
++                                  GFP_KERNEL);
++      }
++}
++
++static int wext_netdev_notifier_call(struct notifier_block *nb,
++                                   unsigned long state, void *ptr)
++{
++      /*
++       * When a netdev changes state in any way, flush all pending messages
++       * to avoid them going out in a strange order, e.g. RTM_NEWLINK after
++       * RTM_DELLINK, or with IFF_UP after without IFF_UP during dev_close()
++       * or similar - all of which could otherwise happen due to delays from
++       * schedule_work().
++       */
++      wireless_nlevent_flush();
++
++      return NOTIFY_OK;
++}
++
++static struct notifier_block wext_netdev_notifier = {
++      .notifier_call = wext_netdev_notifier_call,
++};
++
+ static int __net_init wext_pernet_init(struct net *net)
+ {
+       skb_queue_head_init(&net->wext_nlevents);
+@@ -360,7 +393,12 @@ static struct pernet_operations wext_pernet_ops = {
+ 
+ static int __init wireless_nlevent_init(void)
+ {
+-      return register_pernet_subsys(&wext_pernet_ops);
++      int err = register_pernet_subsys(&wext_pernet_ops);
++
++      if (err)
++              return err;
++
++      return register_netdevice_notifier(&wext_netdev_notifier);
+ }
+ 
+ subsys_initcall(wireless_nlevent_init);
+@@ -368,17 +406,8 @@ subsys_initcall(wireless_nlevent_init);
+ /* Process events generated by the wireless layer or the driver. */
+ static void wireless_nlevent_process(struct work_struct *work)
+ {
+-      struct sk_buff *skb;
+-      struct net *net;
+-
+       rtnl_lock();
+-
+-      for_each_net(net) {
+-              while ((skb = skb_dequeue(&net->wext_nlevents)))
+-                      rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL,
+-                                  GFP_KERNEL);
+-      }
+-
++      wireless_nlevent_flush();
+       rtnl_unlock();
+ }
+ 
+diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c
+index 88632df4381b..dafaf96e0a34 100644
+--- a/scripts/genksyms/genksyms.c
++++ b/scripts/genksyms/genksyms.c
+@@ -423,13 +423,15 @@ static struct string_list *read_node(FILE *f)
+       struct string_list node = {
+               .string = buffer,
+               .tag = SYM_NORMAL };
+-      int c;
++      int c, in_string = 0;
+ 
+       while ((c = fgetc(f)) != EOF) {
+-              if (c == ' ') {
++              if (!in_string && c == ' ') {
+                       if (node.string == buffer)
+                               continue;
+                       break;
++              } else if (c == '"') {
++                      in_string = !in_string;
+               } else if (c == '\n') {
+                       if (node.string == buffer)
+                               return NULL;
+diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
+index 2bb95a7a8809..c14565bde887 100644
+--- a/sound/core/control_compat.c
++++ b/sound/core/control_compat.c
+@@ -170,6 +170,19 @@ struct snd_ctl_elem_value32 {
+         unsigned char reserved[128];
+ };
+ 
++#ifdef CONFIG_X86_X32
++/* x32 has a different alignment for 64bit values from ia32 */
++struct snd_ctl_elem_value_x32 {
++      struct snd_ctl_elem_id id;
++      unsigned int indirect;  /* bit-field causes misalignment */
++      union {
++              s32 integer[128];
++              unsigned char data[512];
++              s64 integer64[64];
++      } value;
++      unsigned char reserved[128];
++};
++#endif /* CONFIG_X86_X32 */
+ 
+ /* get the value type and count of the control */
+ static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id,
+@@ -219,9 +232,11 @@ static int get_elem_size(int type, int count)
+ 
+ static int copy_ctl_value_from_user(struct snd_card *card,
+                                   struct snd_ctl_elem_value *data,
+-                                  struct snd_ctl_elem_value32 __user *data32,
++                                  void __user *userdata,
++                                  void __user *valuep,
+                                   int *typep, int *countp)
+ {
++      struct snd_ctl_elem_value32 __user *data32 = userdata;
+       int i, type, size;
+       int uninitialized_var(count);
+       unsigned int indirect;
+@@ -239,8 +254,9 @@ static int copy_ctl_value_from_user(struct snd_card *card,
+       if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
+           type == SNDRV_CTL_ELEM_TYPE_INTEGER) {
+               for (i = 0; i < count; i++) {
++                      s32 __user *intp = valuep;
+                       int val;
+-                      if (get_user(val, &data32->value.integer[i]))
++                      if (get_user(val, &intp[i]))
+                               return -EFAULT;
+                       data->value.integer.value[i] = val;
+               }
+@@ -250,8 +266,7 @@ static int copy_ctl_value_from_user(struct snd_card *card,
+                       printk(KERN_ERR "snd_ioctl32_ctl_elem_value: unknown 
type %d\n", type);
+                       return -EINVAL;
+               }
+-              if (copy_from_user(data->value.bytes.data,
+-                                 data32->value.data, size))
++              if (copy_from_user(data->value.bytes.data, valuep, size))
+                       return -EFAULT;
+       }
+ 
+@@ -261,7 +276,8 @@ static int copy_ctl_value_from_user(struct snd_card *card,
+ }
+ 
+ /* restore the value to 32bit */
+-static int copy_ctl_value_to_user(struct snd_ctl_elem_value32 __user *data32,
++static int copy_ctl_value_to_user(void __user *userdata,
++                                void __user *valuep,
+                                 struct snd_ctl_elem_value *data,
+                                 int type, int count)
+ {
+@@ -270,22 +286,22 @@ static int copy_ctl_value_to_user(struct 
snd_ctl_elem_value32 __user *data32,
+       if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
+           type == SNDRV_CTL_ELEM_TYPE_INTEGER) {
+               for (i = 0; i < count; i++) {
++                      s32 __user *intp = valuep;
+                       int val;
+                       val = data->value.integer.value[i];
+-                      if (put_user(val, &data32->value.integer[i]))
++                      if (put_user(val, &intp[i]))
+                               return -EFAULT;
+               }
+       } else {
+               size = get_elem_size(type, count);
+-              if (copy_to_user(data32->value.data,
+-                               data->value.bytes.data, size))
++              if (copy_to_user(valuep, data->value.bytes.data, size))
+                       return -EFAULT;
+       }
+       return 0;
+ }
+ 
+-static int snd_ctl_elem_read_user_compat(struct snd_card *card, 
+-                                       struct snd_ctl_elem_value32 __user 
*data32)
++static int ctl_elem_read_user(struct snd_card *card,
++                            void __user *userdata, void __user *valuep)
+ {
+       struct snd_ctl_elem_value *data;
+       int err, type, count;
+@@ -294,7 +310,9 @@ static int snd_ctl_elem_read_user_compat(struct snd_card 
*card,
+       if (data == NULL)
+               return -ENOMEM;
+ 
+-      if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) 
< 0)
++      err = copy_ctl_value_from_user(card, data, userdata, valuep,
++                                     &type, &count);
++      if (err < 0)
+               goto error;
+ 
+       snd_power_lock(card);
+@@ -303,14 +321,15 @@ static int snd_ctl_elem_read_user_compat(struct snd_card 
*card,
+               err = snd_ctl_elem_read(card, data);
+       snd_power_unlock(card);
+       if (err >= 0)
+-              err = copy_ctl_value_to_user(data32, data, type, count);
++              err = copy_ctl_value_to_user(userdata, valuep, data,
++                                           type, count);
+  error:
+       kfree(data);
+       return err;
+ }
+ 
+-static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
+-                                        struct snd_ctl_elem_value32 __user 
*data32)
++static int ctl_elem_write_user(struct snd_ctl_file *file,
++                             void __user *userdata, void __user *valuep)
+ {
+       struct snd_ctl_elem_value *data;
+       struct snd_card *card = file->card;
+@@ -320,7 +339,9 @@ static int snd_ctl_elem_write_user_compat(struct 
snd_ctl_file *file,
+       if (data == NULL)
+               return -ENOMEM;
+ 
+-      if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) 
< 0)
++      err = copy_ctl_value_from_user(card, data, userdata, valuep,
++                                     &type, &count);
++      if (err < 0)
+               goto error;
+ 
+       snd_power_lock(card);
+@@ -329,12 +350,39 @@ static int snd_ctl_elem_write_user_compat(struct 
snd_ctl_file *file,
+               err = snd_ctl_elem_write(card, file, data);
+       snd_power_unlock(card);
+       if (err >= 0)
+-              err = copy_ctl_value_to_user(data32, data, type, count);
++              err = copy_ctl_value_to_user(userdata, valuep, data,
++                                           type, count);
+  error:
+       kfree(data);
+       return err;
+ }
+ 
++static int snd_ctl_elem_read_user_compat(struct snd_card *card,
++                                       struct snd_ctl_elem_value32 __user 
*data32)
++{
++      return ctl_elem_read_user(card, data32, &data32->value);
++}
++
++static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
++                                        struct snd_ctl_elem_value32 __user 
*data32)
++{
++      return ctl_elem_write_user(file, data32, &data32->value);
++}
++
++#ifdef CONFIG_X86_X32
++static int snd_ctl_elem_read_user_x32(struct snd_card *card,
++                                    struct snd_ctl_elem_value_x32 __user 
*data32)
++{
++      return ctl_elem_read_user(card, data32, &data32->value);
++}
++
++static int snd_ctl_elem_write_user_x32(struct snd_ctl_file *file,
++                                     struct snd_ctl_elem_value_x32 __user 
*data32)
++{
++      return ctl_elem_write_user(file, data32, &data32->value);
++}
++#endif /* CONFIG_X86_X32 */
++
+ /* add or replace a user control */
+ static int snd_ctl_elem_add_compat(struct snd_ctl_file *file,
+                                  struct snd_ctl_elem_info32 __user *data32,
+@@ -393,6 +441,10 @@ enum {
+       SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct 
snd_ctl_elem_value32),
+       SNDRV_CTL_IOCTL_ELEM_ADD32 = _IOWR('U', 0x17, struct 
snd_ctl_elem_info32),
+       SNDRV_CTL_IOCTL_ELEM_REPLACE32 = _IOWR('U', 0x18, struct 
snd_ctl_elem_info32),
++#ifdef CONFIG_X86_X32
++      SNDRV_CTL_IOCTL_ELEM_READ_X32 = _IOWR('U', 0x12, struct 
snd_ctl_elem_value_x32),
++      SNDRV_CTL_IOCTL_ELEM_WRITE_X32 = _IOWR('U', 0x13, struct 
snd_ctl_elem_value_x32),
++#endif /* CONFIG_X86_X32 */
+ };
+ 
+ static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, 
unsigned long arg)
+@@ -431,6 +483,12 @@ static inline long snd_ctl_ioctl_compat(struct file 
*file, unsigned int cmd, uns
+               return snd_ctl_elem_add_compat(ctl, argp, 0);
+       case SNDRV_CTL_IOCTL_ELEM_REPLACE32:
+               return snd_ctl_elem_add_compat(ctl, argp, 1);
++#ifdef CONFIG_X86_X32
++      case SNDRV_CTL_IOCTL_ELEM_READ_X32:
++              return snd_ctl_elem_read_user_x32(ctl->card, argp);
++      case SNDRV_CTL_IOCTL_ELEM_WRITE_X32:
++              return snd_ctl_elem_write_user_x32(ctl, argp);
++#endif /* CONFIG_X86_X32 */
+       }
+ 
+       down_read(&snd_ioctl_rwsem);
+diff --git a/sound/core/rawmidi_compat.c b/sound/core/rawmidi_compat.c
+index 5268c1f58c25..09a89094dcf7 100644
+--- a/sound/core/rawmidi_compat.c
++++ b/sound/core/rawmidi_compat.c
+@@ -94,9 +94,58 @@ static int snd_rawmidi_ioctl_status_compat(struct 
snd_rawmidi_file *rfile,
+       return 0;
+ }
+ 
++#ifdef CONFIG_X86_X32
++/* X32 ABI has 64bit timespec and 64bit alignment */
++struct snd_rawmidi_status_x32 {
++      s32 stream;
++      u32 rsvd; /* alignment */
++      struct timespec tstamp;
++      u32 avail;
++      u32 xruns;
++      unsigned char reserved[16];
++} __attribute__((packed));
++
++#define put_timespec(src, dst) copy_to_user(dst, src, sizeof(*dst))
++
++static int snd_rawmidi_ioctl_status_x32(struct snd_rawmidi_file *rfile,
++                                      struct snd_rawmidi_status_x32 __user 
*src)
++{
++      int err;
++      struct snd_rawmidi_status status;
++
++      if (rfile->output == NULL)
++              return -EINVAL;
++      if (get_user(status.stream, &src->stream))
++              return -EFAULT;
++
++      switch (status.stream) {
++      case SNDRV_RAWMIDI_STREAM_OUTPUT:
++              err = snd_rawmidi_output_status(rfile->output, &status);
++              break;
++      case SNDRV_RAWMIDI_STREAM_INPUT:
++              err = snd_rawmidi_input_status(rfile->input, &status);
++              break;
++      default:
++              return -EINVAL;
++      }
++      if (err < 0)
++              return err;
++
++      if (put_timespec(&status.tstamp, &src->tstamp) ||
++          put_user(status.avail, &src->avail) ||
++          put_user(status.xruns, &src->xruns))
++              return -EFAULT;
++
++      return 0;
++}
++#endif /* CONFIG_X86_X32 */
++
+ enum {
+       SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR('W', 0x10, struct 
snd_rawmidi_params32),
+       SNDRV_RAWMIDI_IOCTL_STATUS32 = _IOWR('W', 0x20, struct 
snd_rawmidi_status32),
++#ifdef CONFIG_X86_X32
++      SNDRV_RAWMIDI_IOCTL_STATUS_X32 = _IOWR('W', 0x20, struct 
snd_rawmidi_status_x32),
++#endif /* CONFIG_X86_X32 */
+ };
+ 
+ static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, 
unsigned long arg)
+@@ -115,6 +164,10 @@ static long snd_rawmidi_ioctl_compat(struct file *file, 
unsigned int cmd, unsign
+               return snd_rawmidi_ioctl_params_compat(rfile, argp);
+       case SNDRV_RAWMIDI_IOCTL_STATUS32:
+               return snd_rawmidi_ioctl_status_compat(rfile, argp);
++#ifdef CONFIG_X86_X32
++      case SNDRV_RAWMIDI_IOCTL_STATUS_X32:
++              return snd_rawmidi_ioctl_status_x32(rfile, argp);
++#endif /* CONFIG_X86_X32 */
+       }
+       return -ENOIOCTLCMD;
+ }
+diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
+index 8d4d5e853efe..ab774954c985 100644
+--- a/sound/core/seq/oss/seq_oss.c
++++ b/sound/core/seq/oss/seq_oss.c
+@@ -150,8 +150,6 @@ odev_release(struct inode *inode, struct file *file)
+       if ((dp = file->private_data) == NULL)
+               return 0;
+ 
+-      snd_seq_oss_drain_write(dp);
+-
+       mutex_lock(&register_mutex);
+       snd_seq_oss_release(dp);
+       mutex_unlock(&register_mutex);
+diff --git a/sound/core/seq/oss/seq_oss_device.h 
b/sound/core/seq/oss/seq_oss_device.h
+index c0154a959d55..2464112b08ad 100644
+--- a/sound/core/seq/oss/seq_oss_device.h
++++ b/sound/core/seq/oss/seq_oss_device.h
+@@ -131,7 +131,6 @@ int snd_seq_oss_write(struct seq_oss_devinfo *dp, const 
char __user *buf, int co
+ unsigned int snd_seq_oss_poll(struct seq_oss_devinfo *dp, struct file *file, 
poll_table * wait);
+ 
+ void snd_seq_oss_reset(struct seq_oss_devinfo *dp);
+-void snd_seq_oss_drain_write(struct seq_oss_devinfo *dp);
+ 
+ /* */
+ void snd_seq_oss_process_queue(struct seq_oss_devinfo *dp, abstime_t time);
+diff --git a/sound/core/seq/oss/seq_oss_init.c 
b/sound/core/seq/oss/seq_oss_init.c
+index b3f39b5ed742..f9e09e458227 100644
+--- a/sound/core/seq/oss/seq_oss_init.c
++++ b/sound/core/seq/oss/seq_oss_init.c
+@@ -457,23 +457,6 @@ snd_seq_oss_release(struct seq_oss_devinfo *dp)
+ 
+ 
+ /*
+- * Wait until the queue is empty (if we don't have nonblock)
+- */
+-void
+-snd_seq_oss_drain_write(struct seq_oss_devinfo *dp)
+-{
+-      if (! dp->timer->running)
+-              return;
+-      if (is_write_mode(dp->file_mode) && !is_nonblock_mode(dp->file_mode) &&
+-          dp->writeq) {
+-              debug_printk(("syncing..\n"));
+-              while (snd_seq_oss_writeq_sync(dp->writeq))
+-                      ;
+-      }
+-}
+-
+-
+-/*
+  * reset sequencer devices
+  */
+ void
+diff --git a/sound/core/timer_compat.c b/sound/core/timer_compat.c
+index e05802ae6e1b..2e908225d754 100644
+--- a/sound/core/timer_compat.c
++++ b/sound/core/timer_compat.c
+@@ -70,13 +70,14 @@ static int snd_timer_user_status_compat(struct file *file,
+                                       struct snd_timer_status32 __user 
*_status)
+ {
+       struct snd_timer_user *tu;
+-      struct snd_timer_status status;
++      struct snd_timer_status32 status;
+       
+       tu = file->private_data;
+       if (snd_BUG_ON(!tu->timeri))
+               return -ENXIO;
+       memset(&status, 0, sizeof(status));
+-      status.tstamp = tu->tstamp;
++      status.tstamp.tv_sec = tu->tstamp.tv_sec;
++      status.tstamp.tv_nsec = tu->tstamp.tv_nsec;
+       status.resolution = snd_timer_resolution(tu->timeri);
+       status.lost = tu->timeri->lost;
+       status.overrun = tu->overrun;
+@@ -88,12 +89,21 @@ static int snd_timer_user_status_compat(struct file *file,
+       return 0;
+ }
+ 
++#ifdef CONFIG_X86_X32
++/* X32 ABI has the same struct as x86-64 */
++#define snd_timer_user_status_x32(file, s) \
++      snd_timer_user_status(file, s)
++#endif /* CONFIG_X86_X32 */
++
+ /*
+  */
+ 
+ enum {
+       SNDRV_TIMER_IOCTL_INFO32 = _IOR('T', 0x11, struct snd_timer_info32),
+       SNDRV_TIMER_IOCTL_STATUS32 = _IOW('T', 0x14, struct snd_timer_status32),
++#ifdef CONFIG_X86_X32
++      SNDRV_TIMER_IOCTL_STATUS_X32 = _IOW('T', 0x14, struct snd_timer_status),
++#endif /* CONFIG_X86_X32 */
+ };
+ 
+ static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, 
unsigned long arg)
+@@ -122,6 +132,10 @@ static long snd_timer_user_ioctl_compat(struct file 
*file, unsigned int cmd, uns
+               return snd_timer_user_info_compat(file, argp);
+       case SNDRV_TIMER_IOCTL_STATUS32:
+               return snd_timer_user_status_compat(file, argp);
++#ifdef CONFIG_X86_X32
++      case SNDRV_TIMER_IOCTL_STATUS_X32:
++              return snd_timer_user_status_x32(file, argp);
++#endif /* CONFIG_X86_X32 */
+       }
+       return -ENOIOCTLCMD;
+ }
+diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
+index f59a321a6d6a..a15e4e9b2774 100644
+--- a/sound/pci/rme9652/hdsp.c
++++ b/sound/pci/rme9652/hdsp.c
+@@ -2923,7 +2923,7 @@ static int snd_hdsp_get_dds_offset(struct snd_kcontrol 
*kcontrol, struct snd_ctl
+ {
+       struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+ 
+-      ucontrol->value.enumerated.item[0] = hdsp_dds_offset(hdsp);
++      ucontrol->value.integer.value[0] = hdsp_dds_offset(hdsp);
+       return 0;
+ }
+ 
+@@ -2935,7 +2935,7 @@ static int snd_hdsp_put_dds_offset(struct snd_kcontrol 
*kcontrol, struct snd_ctl
+ 
+       if (!snd_hdsp_use_is_exclusive(hdsp))
+               return -EBUSY;
+-      val = ucontrol->value.enumerated.item[0];
++      val = ucontrol->value.integer.value[0];
+       spin_lock_irq(&hdsp->lock);
+       if (val != hdsp_dds_offset(hdsp))
+               change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0;
+diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
+index 9585e316a5c6..2f5565be9347 100644
+--- a/sound/pci/rme9652/hdspm.c
++++ b/sound/pci/rme9652/hdspm.c
+@@ -1602,6 +1602,9 @@ static void hdspm_set_dds_value(struct hdspm *hdspm, int 
rate)
+ {
+       u64 n;
+ 
++      if (snd_BUG_ON(rate <= 0))
++              return;
++
+       if (rate >= 112000)
+               rate /= 4;
+       else if (rate >= 56000)
+@@ -2224,6 +2227,8 @@ static int hdspm_get_system_sample_rate(struct hdspm 
*hdspm)
+               } else {
+                       /* slave mode, return external sample rate */
+                       rate = hdspm_external_sample_rate(hdspm);
++                      if (!rate)
++                              rate = hdspm->system_sample_rate;
+               }
+       }
+ 
+@@ -2269,8 +2274,11 @@ static int snd_hdspm_put_system_sample_rate(struct 
snd_kcontrol *kcontrol,
+                                           ucontrol)
+ {
+       struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
++      int rate = ucontrol->value.integer.value[0];
+ 
+-      hdspm_set_dds_value(hdspm, ucontrol->value.enumerated.item[0]);
++      if (rate < 27000 || rate > 207000)
++              return -EINVAL;
++      hdspm_set_dds_value(hdspm, ucontrol->value.integer.value[0]);
+       return 0;
+ }
+ 
+@@ -4474,7 +4482,7 @@ static int snd_hdspm_get_tco_word_term(struct 
snd_kcontrol *kcontrol,
+ {
+       struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
+ 
+-      ucontrol->value.enumerated.item[0] = hdspm->tco->term;
++      ucontrol->value.integer.value[0] = hdspm->tco->term;
+ 
+       return 0;
+ }
+@@ -4485,8 +4493,8 @@ static int snd_hdspm_put_tco_word_term(struct 
snd_kcontrol *kcontrol,
+ {
+       struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
+ 
+-      if (hdspm->tco->term != ucontrol->value.enumerated.item[0]) {
+-              hdspm->tco->term = ucontrol->value.enumerated.item[0];
++      if (hdspm->tco->term != ucontrol->value.integer.value[0]) {
++              hdspm->tco->term = ucontrol->value.integer.value[0];
+ 
+               hdspm_tco_write(hdspm);
+ 
+diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c
+index 754f88e1fdab..4892966fc1b8 100644
+--- a/sound/soc/codecs/wm8958-dsp2.c
++++ b/sound/soc/codecs/wm8958-dsp2.c
+@@ -459,7 +459,7 @@ static int wm8958_put_mbc_enum(struct snd_kcontrol 
*kcontrol,
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+       struct wm8994 *control = wm8994->wm8994;
+-      int value = ucontrol->value.integer.value[0];
++      int value = ucontrol->value.enumerated.item[0];
+       int reg;
+ 
+       /* Don't allow on the fly reconfiguration */
+@@ -549,7 +549,7 @@ static int wm8958_put_vss_enum(struct snd_kcontrol 
*kcontrol,
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+       struct wm8994 *control = wm8994->wm8994;
+-      int value = ucontrol->value.integer.value[0];
++      int value = ucontrol->value.enumerated.item[0];
+       int reg;
+ 
+       /* Don't allow on the fly reconfiguration */
+@@ -582,7 +582,7 @@ static int wm8958_put_vss_hpf_enum(struct snd_kcontrol 
*kcontrol,
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+       struct wm8994 *control = wm8994->wm8994;
+-      int value = ucontrol->value.integer.value[0];
++      int value = ucontrol->value.enumerated.item[0];
+       int reg;
+ 
+       /* Don't allow on the fly reconfiguration */
+@@ -749,7 +749,7 @@ static int wm8958_put_enh_eq_enum(struct snd_kcontrol 
*kcontrol,
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+       struct wm8994 *control = wm8994->wm8994;
+-      int value = ucontrol->value.integer.value[0];
++      int value = ucontrol->value.enumerated.item[0];
+       int reg;
+ 
+       /* Don't allow on the fly reconfiguration */
+diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
+index d495d019f18b..84e9533ca436 100644
+--- a/sound/soc/codecs/wm8994.c
++++ b/sound/soc/codecs/wm8994.c
+@@ -360,7 +360,7 @@ static int wm8994_put_drc_enum(struct snd_kcontrol 
*kcontrol,
+       struct wm8994 *control = wm8994->wm8994;
+       struct wm8994_pdata *pdata = &control->pdata;
+       int drc = wm8994_get_drc(kcontrol->id.name);
+-      int value = ucontrol->value.integer.value[0];
++      int value = ucontrol->value.enumerated.item[0];
+ 
+       if (drc < 0)
+               return drc;
+@@ -467,7 +467,7 @@ static int wm8994_put_retune_mobile_enum(struct 
snd_kcontrol *kcontrol,
+       struct wm8994 *control = wm8994->wm8994;
+       struct wm8994_pdata *pdata = &control->pdata;
+       int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
+-      int value = ucontrol->value.integer.value[0];
++      int value = ucontrol->value.enumerated.item[0];
+ 
+       if (block < 0)
+               return block;
+diff --git a/tools/testing/selftests/efivarfs/efivarfs.sh 
b/tools/testing/selftests/efivarfs/efivarfs.sh
+index 77edcdcc016b..057278448515 100644
+--- a/tools/testing/selftests/efivarfs/efivarfs.sh
++++ b/tools/testing/selftests/efivarfs/efivarfs.sh
+@@ -88,7 +88,11 @@ test_delete()
+               exit 1
+       fi
+ 
+-      rm $file
++      rm $file 2>/dev/null
++      if [ $? -ne 0 ]; then
++              chattr -i $file
++              rm $file
++      fi
+ 
+       if [ -e $file ]; then
+               echo "$file couldn't be deleted" >&2
+@@ -111,6 +115,7 @@ test_zero_size_delete()
+               exit 1
+       fi
+ 
++      chattr -i $file
+       printf "$attrs" > $file
+ 
+       if [ -e $file ]; then
+@@ -141,7 +146,11 @@ test_valid_filenames()
+                       echo "$file could not be created" >&2
+                       ret=1
+               else
+-                      rm $file
++                      rm $file 2>/dev/null
++                      if [ $? -ne 0 ]; then
++                              chattr -i $file
++                              rm $file
++                      fi
+               fi
+       done
+ 
+@@ -174,7 +183,11 @@ test_invalid_filenames()
+ 
+               if [ -e $file ]; then
+                       echo "Creating $file should have failed" >&2
+-                      rm $file
++                      rm $file 2>/dev/null
++                      if [ $? -ne 0 ]; then
++                              chattr -i $file
++                              rm $file
++                      fi
+                       ret=1
+               fi
+       done
+diff --git a/tools/testing/selftests/efivarfs/open-unlink.c 
b/tools/testing/selftests/efivarfs/open-unlink.c
+index 8c0764407b3c..4af74f733036 100644
+--- a/tools/testing/selftests/efivarfs/open-unlink.c
++++ b/tools/testing/selftests/efivarfs/open-unlink.c
+@@ -1,10 +1,68 @@
++#include <errno.h>
+ #include <stdio.h>
+ #include <stdint.h>
+ #include <stdlib.h>
+ #include <unistd.h>
++#include <sys/ioctl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
++#include <linux/fs.h>
++
++static int set_immutable(const char *path, int immutable)
++{
++      unsigned int flags;
++      int fd;
++      int rc;
++      int error;
++
++      fd = open(path, O_RDONLY);
++      if (fd < 0)
++              return fd;
++
++      rc = ioctl(fd, FS_IOC_GETFLAGS, &flags);
++      if (rc < 0) {
++              error = errno;
++              close(fd);
++              errno = error;
++              return rc;
++      }
++
++      if (immutable)
++              flags |= FS_IMMUTABLE_FL;
++      else
++              flags &= ~FS_IMMUTABLE_FL;
++
++      rc = ioctl(fd, FS_IOC_SETFLAGS, &flags);
++      error = errno;
++      close(fd);
++      errno = error;
++      return rc;
++}
++
++static int get_immutable(const char *path)
++{
++      unsigned int flags;
++      int fd;
++      int rc;
++      int error;
++
++      fd = open(path, O_RDONLY);
++      if (fd < 0)
++              return fd;
++
++      rc = ioctl(fd, FS_IOC_GETFLAGS, &flags);
++      if (rc < 0) {
++              error = errno;
++              close(fd);
++              errno = error;
++              return rc;
++      }
++      close(fd);
++      if (flags & FS_IMMUTABLE_FL)
++              return 1;
++      return 0;
++}
+ 
+ int main(int argc, char **argv)
+ {
+@@ -27,7 +85,7 @@ int main(int argc, char **argv)
+       buf[4] = 0;
+ 
+       /* create a test variable */
+-      fd = open(path, O_WRONLY | O_CREAT);
++      fd = open(path, O_WRONLY | O_CREAT, 0600);
+       if (fd < 0) {
+               perror("open(O_WRONLY)");
+               return EXIT_FAILURE;
+@@ -41,6 +99,18 @@ int main(int argc, char **argv)
+ 
+       close(fd);
+ 
++      rc = get_immutable(path);
++      if (rc < 0) {
++              perror("ioctl(FS_IOC_GETFLAGS)");
++              return EXIT_FAILURE;
++      } else if (rc) {
++              rc = set_immutable(path, 0);
++              if (rc < 0) {
++                      perror("ioctl(FS_IOC_SETFLAGS)");
++                      return EXIT_FAILURE;
++              }
++      }
++
+       fd = open(path, O_RDONLY);
+       if (fd < 0) {
+               perror("open");

Reply via email to