aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--patch1493
1 files changed, 0 insertions, 1493 deletions
diff --git a/patch b/patch
deleted file mode 100644
index d9647df43..000000000
--- a/patch
+++ /dev/null
@@ -1,1493 +0,0 @@
-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 40d4d3bf52c3..4be9e643cef0 100644
---- a/Makefile
-+++ b/Makefile
-@@ -1,6 +1,6 @@
- VERSION = 3
- PATCHLEVEL = 10
--SUBLEVEL = 100
-+SUBLEVEL = 101
- EXTRAVERSION =
- NAME = TOSSUG Baby Fish
-
-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/kvm/vmx.c b/arch/x86/kvm/vmx.c
-index 04cc2fa7744f..335fe70967a8 100644
---- a/arch/x86/kvm/vmx.c
-+++ b/arch/x86/kvm/vmx.c
-@@ -1487,6 +1487,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 41ba726c1ce2..7f2b6dec4b2b 100644
---- a/arch/x86/kvm/x86.c
-+++ b/arch/x86/kvm/x86.c
-@@ -1941,6 +1941,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;
-
-@@ -2074,12 +2076,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;
-@@ -2758,7 +2754,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/crypto/af_alg.c b/crypto/af_alg.c
-index 0ca108f3c840..1aaa555fab56 100644
---- a/crypto/af_alg.c
-+++ b/crypto/af_alg.c
-@@ -125,23 +125,6 @@ int af_alg_release(struct socket *sock)
- }
- EXPORT_SYMBOL_GPL(af_alg_release);
-
--void af_alg_release_parent(struct sock *sk)
--{
-- struct alg_sock *ask = alg_sk(sk);
-- bool last;
--
-- sk = ask->parent;
-- ask = alg_sk(sk);
--
-- lock_sock(sk);
-- last = !--ask->refcnt;
-- release_sock(sk);
--
-- if (last)
-- sock_put(sk);
--}
--EXPORT_SYMBOL_GPL(af_alg_release_parent);
--
- static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
- {
- struct sock *sk = sock->sk;
-@@ -149,7 +132,6 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
- struct sockaddr_alg *sa = (void *)uaddr;
- const struct af_alg_type *type;
- void *private;
-- int err;
-
- if (sock->state == SS_CONNECTED)
- return -EINVAL;
-@@ -175,22 +157,16 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
- return PTR_ERR(private);
- }
-
-- err = -EBUSY;
- lock_sock(sk);
-- if (ask->refcnt)
-- goto unlock;
-
- swap(ask->type, type);
- swap(ask->private, private);
-
-- err = 0;
--
--unlock:
- release_sock(sk);
-
- alg_do_release(type, private);
-
-- return err;
-+ return 0;
- }
-
- static int alg_setkey(struct sock *sk, char __user *ukey,
-@@ -223,15 +199,11 @@ static int alg_setsockopt(struct socket *sock, int level, int optname,
- struct sock *sk = sock->sk;
- struct alg_sock *ask = alg_sk(sk);
- const struct af_alg_type *type;
-- int err = -EBUSY;
-+ int err = -ENOPROTOOPT;
-
- lock_sock(sk);
-- if (ask->refcnt)
-- goto unlock;
--
- type = ask->type;
-
-- err = -ENOPROTOOPT;
- if (level != SOL_ALG || !type)
- goto unlock;
-
-@@ -280,8 +252,7 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)
-
- sk2->sk_family = PF_ALG;
-
-- if (!ask->refcnt++)
-- sock_hold(sk);
-+ sock_hold(sk);
- alg_sk(sk2)->parent = sk;
- alg_sk(sk2)->type = type;
-
-diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
-index 8bd1bb6dbe47..24ae2a694e9b 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;
- }
-@@ -405,35 +407,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 7dbc319e1cf5..9f82b5545edd 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)
- {
-@@ -797,7 +863,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/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 7e787fb90293..d0351bc7b533 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 141aee31884f..5a3655f690d9 100644
---- a/fs/efivarfs/super.c
-+++ b/fs/efivarfs/super.c
-@@ -128,8 +128,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)
-@@ -138,15 +139,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] = '-';
-
-@@ -154,7 +157,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;
-
-@@ -210,7 +214,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/include/crypto/if_alg.h b/include/crypto/if_alg.h
-index 2f38daaab3d7..d61c11170213 100644
---- a/include/crypto/if_alg.h
-+++ b/include/crypto/if_alg.h
-@@ -30,8 +30,6 @@ struct alg_sock {
-
- struct sock *parent;
-
-- unsigned int refcnt;
--
- const struct af_alg_type *type;
- void *private;
- };
-@@ -66,7 +64,6 @@ int af_alg_register_type(const struct af_alg_type *type);
- int af_alg_unregister_type(const struct af_alg_type *type);
-
- int af_alg_release(struct socket *sock);
--void af_alg_release_parent(struct sock *sk);
- int af_alg_accept(struct sock *sk, struct socket *newsock);
-
- int af_alg_make_sg(struct af_alg_sgl *sgl, void __user *addr, int len,
-@@ -83,6 +80,11 @@ static inline struct alg_sock *alg_sk(struct sock *sk)
- return (struct alg_sock *)sk;
- }
-
-+static inline void af_alg_release_parent(struct sock *sk)
-+{
-+ sock_put(alg_sk(sk)->parent);
-+}
-+
- static inline void af_alg_init_completion(struct af_alg_completion *completion)
- {
- init_completion(&completion->completion);
-diff --git a/include/linux/efi.h b/include/linux/efi.h
-index 2bc0ad78d058..63fa51c864ec 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];
-@@ -832,7 +834,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/module.h b/include/linux/module.h
-index 46f1ea01e6f6..761dc2848ffa 100644
---- a/include/linux/module.h
-+++ b/include/linux/module.h
-@@ -220,6 +220,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;
-@@ -308,14 +314,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/tracepoint.h b/include/linux/tracepoint.h
-index 0b2d0cbe0bab..36e5e9998865 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/kernel/module.c b/kernel/module.c
-index 70a4754c001f..f8a4f48b48a9 100644
---- a/kernel/module.c
-+++ b/kernel/module.c
-@@ -179,6 +179,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;
-@@ -2346,8 +2349,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;
-@@ -2356,28 +2371,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)
-@@ -3117,9 +3137,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);
-@@ -3398,9 +3417,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,
-@@ -3410,6 +3429,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))
-@@ -3419,32 +3439,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
-@@ -3540,18 +3560,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;
-@@ -3560,11 +3583,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;
- }
-
-@@ -3603,11 +3627,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/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
-index 31bf2586fb84..864408026202 100644
---- a/net/mac80211/agg-rx.c
-+++ b/net/mac80211/agg-rx.c
-@@ -290,7 +290,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
- }
-
- /* prepare A-MPDU MLME for Rx aggregation */
-- tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL);
-+ tid_agg_rx = kzalloc(sizeof(*tid_agg_rx), GFP_KERNEL);
- if (!tid_agg_rx)
- goto end;
-
-diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
-index f3bbea1eb9e7..13f10aab9213 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/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/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 6e746c7474bf..cda3cf23474b 100644
---- a/sound/soc/codecs/wm8994.c
-+++ b/sound/soc/codecs/wm8994.c
-@@ -361,7 +361,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;
-@@ -468,7 +468,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");