--- /dev/null
+From ba3fd3d6cf4a97bcb934614295aa2ee4d2cd6ac9 Mon Sep 17 00:00:00 2001
+From: "samix.lebsir" <samix.lebsir@intel.com>
+Date: Mon, 13 Aug 2012 13:44:22 +0100
+Subject: char: n_gsm: remove message filtering for contipated DLCI
+
+From: "samix.lebsir" <samix.lebsir@intel.com>
+
+commit 10c6c383e43565c9c6ec07ff8eb2825f8091bdf0 upstream.
+
+The design of uplink flow control in the mux driver is
+that for constipated channels data will backup into the
+per-channel fifos, and any messages that make it to the
+outbound message queue will still go out.
+Code was added to also stop messages that were in the outbound
+queue but this requires filtering through all the messages on the
+queue for stopped dlcis and changes some of the mux logic unneccessarily.
+
+The message fiiltering was removed to be in line w/ the original design
+as the message filtering does not provide any solution.
+Extra debug messages used during investigation were also removed.
+
+Signed-off-by: samix.lebsir <samix.lebsir@intel.com>
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/n_gsm.c | 25 +------------------------
+ 1 file changed, 1 insertion(+), 24 deletions(-)
+
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -691,10 +691,6 @@ static void gsm_data_kick(struct gsm_mux
+ msg = msg->next;
+ continue;
+ }
+- if (gsm->dlci[msg->addr]->constipated) {
+- msg = msg->next;
+- continue;
+- }
+ if (gsm->encoding != 0) {
+ gsm->txframe[0] = GSM1_SOF;
+ len = gsm_stuff_frame(msg->data,
+@@ -748,8 +744,6 @@ static void __gsm_data_queue(struct gsm_
+ u8 *dp = msg->data;
+ u8 *fcs = dp + msg->len;
+
+- WARN_ONCE(dlci->constipated, "%s: queueing from a constipated DLCI",
+- __func__);
+ /* Fill in the header */
+ if (gsm->encoding == 0) {
+ if (msg->len < 128)
+@@ -959,9 +953,6 @@ static void gsm_dlci_data_sweep(struct g
+ break;
+ dlci = gsm->dlci[i];
+ if (dlci == NULL || dlci->constipated) {
+- if (dlci && (debug & 0x20))
+- pr_info("%s: DLCI %d is constipated",
+- __func__, i);
+ i++;
+ continue;
+ }
+@@ -991,12 +982,8 @@ static void gsm_dlci_data_kick(struct gs
+ unsigned long flags;
+ int sweep;
+
+- if (dlci->constipated) {
+- if (debug & 0x20)
+- pr_info("%s: DLCI %d is constipated",
+- __func__, dlci->addr);
++ if (dlci->constipated)
+ return;
+- }
+
+ spin_lock_irqsave(&dlci->gsm->tx_lock, flags);
+ /* If we have nothing running then we need to fire up */
+@@ -1072,15 +1059,9 @@ static void gsm_process_modem(struct tty
+ /* Flow control/ready to communicate */
+ fc = (modem & MDM_FC) || !(modem & MDM_RTR);
+ if (fc && !dlci->constipated) {
+- if (debug & 0x20)
+- pr_info("%s: DLCI %d START constipated (tx_bytes=%d)",
+- __func__, dlci->addr, dlci->gsm->tx_bytes);
+ /* Need to throttle our output on this device */
+ dlci->constipated = 1;
+ } else if (!fc && dlci->constipated) {
+- if (debug & 0x20)
+- pr_info("%s: DLCI %d END constipated (tx_bytes=%d)",
+- __func__, dlci->addr, dlci->gsm->tx_bytes);
+ dlci->constipated = 0;
+ gsm_dlci_data_kick(dlci);
+ }
+@@ -1257,8 +1238,6 @@ static void gsm_control_message(struct g
+ break;
+ case CMD_FCON:
+ /* Modem can accept data again */
+- if (debug & 0x20)
+- pr_info("%s: GSM END constipation", __func__);
+ gsm->constipated = 0;
+ gsm_control_reply(gsm, CMD_FCON, NULL, 0);
+ /* Kick the link in case it is idling */
+@@ -1268,8 +1247,6 @@ static void gsm_control_message(struct g
+ break;
+ case CMD_FCOFF:
+ /* Modem wants us to STFU */
+- if (debug & 0x20)
+- pr_info("%s: GSM START constipation", __func__);
+ gsm->constipated = 1;
+ gsm_control_reply(gsm, CMD_FCOFF, NULL, 0);
+ break;
--- /dev/null
+From 7feecf3f2b587e535550bb3e7bf75b2fee06fccf Mon Sep 17 00:00:00 2001
+From: Josh Boyer <jwboyer@redhat.com>
+Date: Mon, 11 Mar 2013 17:48:53 -0400
+Subject: efi: be more paranoid about available space when creating variables
+
+From: Josh Boyer <jwboyer@redhat.com>
+
+commit 68d929862e29a8b52a7f2f2f86a0600423b093cd upstream.
+
+UEFI variables are typically stored in flash. For various reasons, avaiable
+space is typically not reclaimed immediately upon the deletion of a
+variable - instead, the system will garbage collect during initialisation
+after a reboot.
+
+Some systems appear to handle this garbage collection extremely poorly,
+failing if more than 50% of the system flash is in use. This can result in
+the machine refusing to boot. The safest thing to do for the moment is to
+forbid writes if they'd end up using more than half of the storage space.
+We can make this more finegrained later if we come up with a method for
+identifying the broken machines.
+
+Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+[bwh: Backported to 3.2:
+ - Drop efivarfs changes and unused check_var_size()
+ - Add error codes to include/linux/efi.h, added upstream by
+ commit 5d9db883761a ('efi: Add support for a UEFI variable filesystem')
+ - Add efi_status_to_err(), added upstream by commit 7253eaba7b17
+ ('efivarfs: Return an error if we fail to read a variable')]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/firmware/efivars.c | 88 +++++++++++++++++++++++++++++++++++++++------
+ include/linux/efi.h | 5 ++
+ 2 files changed, 82 insertions(+), 11 deletions(-)
+
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -409,6 +409,30 @@ get_var_data(struct efivars *efivars, st
+ return status;
+ }
+
++static efi_status_t
++check_var_size_locked(struct efivars *efivars, u32 attributes,
++ unsigned long size)
++{
++ u64 storage_size, remaining_size, max_size;
++ efi_status_t status;
++ const struct efivar_operations *fops = efivars->ops;
++
++ if (!efivars->ops->query_variable_info)
++ return EFI_UNSUPPORTED;
++
++ status = fops->query_variable_info(attributes, &storage_size,
++ &remaining_size, &max_size);
++
++ if (status != EFI_SUCCESS)
++ return status;
++
++ if (!storage_size || size > remaining_size || size > max_size ||
++ (remaining_size - size) < (storage_size / 2))
++ return EFI_OUT_OF_RESOURCES;
++
++ return status;
++}
++
+ static ssize_t
+ efivar_guid_read(struct efivar_entry *entry, char *buf)
+ {
+@@ -530,11 +554,16 @@ efivar_store_raw(struct efivar_entry *en
+ }
+
+ spin_lock_irq(&efivars->lock);
+- status = efivars->ops->set_variable(new_var->VariableName,
+- &new_var->VendorGuid,
+- new_var->Attributes,
+- new_var->DataSize,
+- new_var->Data);
++
++ status = check_var_size_locked(efivars, new_var->Attributes,
++ new_var->DataSize + utf16_strsize(new_var->VariableName, 1024));
++
++ if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED)
++ status = efivars->ops->set_variable(new_var->VariableName,
++ &new_var->VendorGuid,
++ new_var->Attributes,
++ new_var->DataSize,
++ new_var->Data);
+
+ spin_unlock_irq(&efivars->lock);
+
+@@ -641,6 +670,36 @@ efivar_unregister(struct efivar_entry *v
+ kobject_put(&var->kobj);
+ }
+
++static int efi_status_to_err(efi_status_t status)
++{
++ int err;
++
++ switch (status) {
++ case EFI_INVALID_PARAMETER:
++ err = -EINVAL;
++ break;
++ case EFI_OUT_OF_RESOURCES:
++ err = -ENOSPC;
++ break;
++ case EFI_DEVICE_ERROR:
++ err = -EIO;
++ break;
++ case EFI_WRITE_PROTECTED:
++ err = -EROFS;
++ break;
++ case EFI_SECURITY_VIOLATION:
++ err = -EACCES;
++ break;
++ case EFI_NOT_FOUND:
++ err = -ENOENT;
++ break;
++ default:
++ err = -EINVAL;
++ }
++
++ return err;
++}
++
+ #ifdef CONFIG_PSTORE
+
+ static int efi_pstore_open(struct pstore_info *psi)
+@@ -711,7 +770,6 @@ static int efi_pstore_write(enum pstore_
+ struct efivars *efivars = psi->data;
+ struct efivar_entry *entry, *found = NULL;
+ int i, ret = 0;
+- u64 storage_space, remaining_space, max_variable_size;
+ efi_status_t status = EFI_NOT_FOUND;
+ unsigned long flags;
+
+@@ -725,11 +783,11 @@ static int efi_pstore_write(enum pstore_
+ * size: a size of logging data
+ * DUMP_NAME_LEN * 2: a maximum size of variable name
+ */
+- status = efivars->ops->query_variable_info(PSTORE_EFI_ATTRIBUTES,
+- &storage_space,
+- &remaining_space,
+- &max_variable_size);
+- if (status || remaining_space < size + DUMP_NAME_LEN * 2) {
++
++ status = check_var_size_locked(efivars, PSTORE_EFI_ATTRIBUTES,
++ size + DUMP_NAME_LEN * 2);
++
++ if (status) {
+ spin_unlock_irqrestore(&efivars->lock, flags);
+ *id = part;
+ return -ENOSPC;
+@@ -877,6 +935,14 @@ static ssize_t efivar_create(struct file
+ return -EINVAL;
+ }
+
++ status = check_var_size_locked(efivars, new_var->Attributes,
++ new_var->DataSize + utf16_strsize(new_var->VariableName, 1024));
++
++ if (status && status != EFI_UNSUPPORTED) {
++ spin_unlock_irq(&efivars->lock);
++ return efi_status_to_err(status);
++ }
++
+ /* now *really* create the variable via EFI */
+ status = efivars->ops->set_variable(new_var->VariableName,
+ &new_var->VendorGuid,
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -29,7 +29,12 @@
+ #define EFI_UNSUPPORTED ( 3 | (1UL << (BITS_PER_LONG-1)))
+ #define EFI_BAD_BUFFER_SIZE ( 4 | (1UL << (BITS_PER_LONG-1)))
+ #define EFI_BUFFER_TOO_SMALL ( 5 | (1UL << (BITS_PER_LONG-1)))
++#define EFI_NOT_READY ( 6 | (1UL << (BITS_PER_LONG-1)))
++#define EFI_DEVICE_ERROR ( 7 | (1UL << (BITS_PER_LONG-1)))
++#define EFI_WRITE_PROTECTED ( 8 | (1UL << (BITS_PER_LONG-1)))
++#define EFI_OUT_OF_RESOURCES ( 9 | (1UL << (BITS_PER_LONG-1)))
+ #define EFI_NOT_FOUND (14 | (1UL << (BITS_PER_LONG-1)))
++#define EFI_SECURITY_VIOLATION (26 | (1UL << (BITS_PER_LONG-1)))
+
+ typedef unsigned long efi_status_t;
+ typedef u8 efi_bool_t;
--- /dev/null
+From 316d0bb70f66a2682c19494f2d1fdebfa00de1ac Mon Sep 17 00:00:00 2001
+From: Seiji Aguchi <seiji.aguchi@hds.com>
+Date: Wed, 14 Nov 2012 20:25:37 +0000
+Subject: efi_pstore: Check remaining space with QueryVariableInfo() before writing data
+
+From: Seiji Aguchi <seiji.aguchi@hds.com>
+
+commit d80a361d779a9f19498943d1ca84243209cd5647 upstream.
+
+[Issue]
+
+As discussed in a thread below, Running out of space in EFI isn't a well-tested scenario.
+And we wouldn't expect all firmware to handle it gracefully.
+http://marc.info/?l=linux-kernel&m=134305325801789&w=2
+
+On the other hand, current efi_pstore doesn't check a remaining space of storage at writing time.
+Therefore, efi_pstore may not work if it tries to write a large amount of data.
+
+[Patch Description]
+
+To avoid handling the situation above, this patch checks if there is a space enough to log with
+QueryVariableInfo() before writing data.
+
+Signed-off-by: Seiji Aguchi <seiji.aguchi@hds.com>
+Acked-by: Mike Waychison <mikew@google.com>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/firmware/efivars.c | 18 ++++++++++++++++++
+ include/linux/efi.h | 1 +
+ 2 files changed, 19 insertions(+)
+
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -710,12 +710,29 @@ static int efi_pstore_write(enum pstore_
+ struct efivars *efivars = psi->data;
+ struct efivar_entry *entry, *found = NULL;
+ int i, ret = 0;
++ u64 storage_space, remaining_space, max_variable_size;
++ efi_status_t status = EFI_NOT_FOUND;
+
+ sprintf(stub_name, "dump-type%u-%u-", type, part);
+ sprintf(name, "%s%lu", stub_name, get_seconds());
+
+ spin_lock(&efivars->lock);
+
++ /*
++ * Check if there is a space enough to log.
++ * size: a size of logging data
++ * DUMP_NAME_LEN * 2: a maximum size of variable name
++ */
++ status = efivars->ops->query_variable_info(PSTORE_EFI_ATTRIBUTES,
++ &storage_space,
++ &remaining_space,
++ &max_variable_size);
++ if (status || remaining_space < size + DUMP_NAME_LEN * 2) {
++ spin_unlock(&efivars->lock);
++ *id = part;
++ return -ENOSPC;
++ }
++
+ for (i = 0; i < DUMP_NAME_LEN; i++)
+ efi_name[i] = stub_name[i];
+
+@@ -1324,6 +1341,7 @@ efivars_init(void)
+ ops.get_variable = efi.get_variable;
+ ops.set_variable = efi.set_variable;
+ ops.get_next_variable = efi.get_next_variable;
++ ops.query_variable_info = efi.query_variable_info;
+ error = register_efivars(&__efivars, &ops, efi_kobj);
+ if (error)
+ goto err_put;
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -652,6 +652,7 @@ struct efivar_operations {
+ efi_get_variable_t *get_variable;
+ efi_get_next_variable_t *get_next_variable;
+ efi_set_variable_t *set_variable;
++ efi_query_variable_info_t *query_variable_info;
+ };
+
+ struct efivars {
--- /dev/null
+From ed9dc8ce7a1c8115dba9483a9b51df8b63a2e0ef Mon Sep 17 00:00:00 2001
+From: Seth Forshee <seth.forshee@canonical.com>
+Date: Thu, 7 Mar 2013 11:40:17 -0600
+Subject: efivars: Allow disabling use as a pstore backend
+
+From: Seth Forshee <seth.forshee@canonical.com>
+
+commit ed9dc8ce7a1c8115dba9483a9b51df8b63a2e0ef upstream.
+
+Add a new option, CONFIG_EFI_VARS_PSTORE, which can be set to N to
+avoid using efivars as a backend to pstore, as some users may want to
+compile out the code completely.
+
+Set the default to Y to maintain backwards compatability, since this
+feature has always been enabled until now.
+
+Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
+Cc: Josh Boyer <jwboyer@redhat.com>
+Cc: Matthew Garrett <mjg59@srcf.ucam.org>
+Cc: Seiji Aguchi <seiji.aguchi@hds.com>
+Cc: Tony Luck <tony.luck@intel.com>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+[xr: Backported to 3.4: adjust context]
+Signed-off-by: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/firmware/Kconfig | 9 ++++++
+ drivers/firmware/efivars.c | 63 ++++++++++++++-------------------------------
+ 2 files changed, 29 insertions(+), 43 deletions(-)
+
+--- a/drivers/firmware/Kconfig
++++ b/drivers/firmware/Kconfig
+@@ -53,6 +53,15 @@ config EFI_VARS
+ Subsequent efibootmgr releases may be found at:
+ <http://linux.dell.com/efibootmgr>
+
++config EFI_VARS_PSTORE
++ bool "Register efivars backend for pstore"
++ depends on EFI_VARS && PSTORE
++ default y
++ help
++ Say Y here to enable use efivars as a backend to pstore. This
++ will allow writing console messages, crash dumps, or anything
++ else supported by pstore to EFI variables.
++
+ config EFI_PCDP
+ bool "Console device selection via EFI PCDP or HCDP table"
+ depends on ACPI && EFI && IA64
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -662,8 +662,6 @@ static struct kobj_type efivar_ktype = {
+ .default_attrs = def_attrs,
+ };
+
+-static struct pstore_info efi_pstore_info;
+-
+ static inline void
+ efivar_unregister(struct efivar_entry *var)
+ {
+@@ -700,7 +698,7 @@ static int efi_status_to_err(efi_status_
+ return err;
+ }
+
+-#ifdef CONFIG_PSTORE
++#ifdef CONFIG_EFI_VARS_PSTORE
+
+ static int efi_pstore_open(struct pstore_info *psi)
+ {
+@@ -853,37 +851,6 @@ static int efi_pstore_erase(enum pstore_
+
+ return 0;
+ }
+-#else
+-static int efi_pstore_open(struct pstore_info *psi)
+-{
+- return 0;
+-}
+-
+-static int efi_pstore_close(struct pstore_info *psi)
+-{
+- return 0;
+-}
+-
+-static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
+- struct timespec *timespec,
+- char **buf, struct pstore_info *psi)
+-{
+- return -1;
+-}
+-
+-static int efi_pstore_write(enum pstore_type_id type,
+- enum kmsg_dump_reason reason, u64 *id,
+- unsigned int part, size_t size, struct pstore_info *psi)
+-{
+- return 0;
+-}
+-
+-static int efi_pstore_erase(enum pstore_type_id type, u64 id,
+- struct pstore_info *psi)
+-{
+- return 0;
+-}
+-#endif
+
+ static struct pstore_info efi_pstore_info = {
+ .owner = THIS_MODULE,
+@@ -895,6 +862,24 @@ static struct pstore_info efi_pstore_inf
+ .erase = efi_pstore_erase,
+ };
+
++static void efivar_pstore_register(struct efivars *efivars)
++{
++ efivars->efi_pstore_info = efi_pstore_info;
++ efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
++ if (efivars->efi_pstore_info.buf) {
++ efivars->efi_pstore_info.bufsize = 1024;
++ efivars->efi_pstore_info.data = efivars;
++ spin_lock_init(&efivars->efi_pstore_info.buf_lock);
++ pstore_register(&efivars->efi_pstore_info);
++ }
++}
++#else
++static void efivar_pstore_register(struct efivars *efivars)
++{
++ return;
++}
++#endif
++
+ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t pos, size_t count)
+@@ -1365,15 +1350,7 @@ int register_efivars(struct efivars *efi
+ if (error)
+ unregister_efivars(efivars);
+
+- efivars->efi_pstore_info = efi_pstore_info;
+-
+- efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
+- if (efivars->efi_pstore_info.buf) {
+- efivars->efi_pstore_info.bufsize = 1024;
+- efivars->efi_pstore_info.data = efivars;
+- spin_lock_init(&efivars->efi_pstore_info.buf_lock);
+- pstore_register(&efivars->efi_pstore_info);
+- }
++ efivar_pstore_register(efivars);
+
+ out:
+ kfree(variable_name);
--- /dev/null
+From 3b048fc196139b840d79b316405bede9b5d3c4c2 Mon Sep 17 00:00:00 2001
+From: Josh Boyer <jwboyer@redhat.com>
+Date: Mon, 11 Mar 2013 17:47:42 -0400
+Subject: efivars: Disable external interrupt while holding efivars->lock
+
+From: Josh Boyer <jwboyer@redhat.com>
+
+commit 81fa4e581d9283f7992a0d8c534bb141eb840a14 upstream.
+
+[Problem]
+There is a scenario which efi_pstore fails to log messages in a panic case.
+
+ - CPUA holds an efi_var->lock in either efivarfs parts
+ or efi_pstore with interrupt enabled.
+ - CPUB panics and sends IPI to CPUA in smp_send_stop().
+ - CPUA stops with holding the lock.
+ - CPUB kicks efi_pstore_write() via kmsg_dump(KSMG_DUMP_PANIC)
+ but it returns without logging messages.
+
+[Patch Description]
+This patch disables an external interruption while holding efivars->lock
+as follows.
+
+In efi_pstore_write() and get_var_data(), spin_lock/spin_unlock is
+replaced by spin_lock_irqsave/spin_unlock_irqrestore because they may
+be called in an interrupt context.
+
+In other functions, they are replaced by spin_lock_irq/spin_unlock_irq.
+because they are all called from a process context.
+
+By applying this patch, we can avoid the problem above with
+a following senario.
+
+ - CPUA holds an efi_var->lock with interrupt disabled.
+ - CPUB panics and sends IPI to CPUA in smp_send_stop().
+ - CPUA receives the IPI after releasing the lock because it is
+ disabling interrupt while holding the lock.
+ - CPUB waits for one sec until CPUA releases the lock.
+ - CPUB kicks efi_pstore_write() via kmsg_dump(KSMG_DUMP_PANIC)
+ And it can hold the lock successfully.
+
+Signed-off-by: Seiji Aguchi <seiji.aguchi@hds.com>
+Acked-by: Mike Waychison <mikew@google.com>
+Acked-by: Matt Fleming <matt.fleming@intel.com>
+Signed-off-by: Tony Luck <tony.luck@intel.com>
+[bwh: Backported to 3.2:
+ - Drop efivarfs changes
+ - Adjust context
+ - Drop change to efi_pstore_erase(), which is implemented using
+ efi_pstore_write() here]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/firmware/efivars.c | 44 +++++++++++++++++++++++---------------------
+ 1 file changed, 23 insertions(+), 21 deletions(-)
+
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -396,10 +396,11 @@ static efi_status_t
+ get_var_data(struct efivars *efivars, struct efi_variable *var)
+ {
+ efi_status_t status;
++ unsigned long flags;
+
+- spin_lock(&efivars->lock);
++ spin_lock_irqsave(&efivars->lock, flags);
+ status = get_var_data_locked(efivars, var);
+- spin_unlock(&efivars->lock);
++ spin_unlock_irqrestore(&efivars->lock, flags);
+
+ if (status != EFI_SUCCESS) {
+ printk(KERN_WARNING "efivars: get_variable() failed 0x%lx!\n",
+@@ -528,14 +529,14 @@ efivar_store_raw(struct efivar_entry *en
+ return -EINVAL;
+ }
+
+- spin_lock(&efivars->lock);
++ spin_lock_irq(&efivars->lock);
+ status = efivars->ops->set_variable(new_var->VariableName,
+ &new_var->VendorGuid,
+ new_var->Attributes,
+ new_var->DataSize,
+ new_var->Data);
+
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+
+ if (status != EFI_SUCCESS) {
+ printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
+@@ -646,7 +647,7 @@ static int efi_pstore_open(struct pstore
+ {
+ struct efivars *efivars = psi->data;
+
+- spin_lock(&efivars->lock);
++ spin_lock_irq(&efivars->lock);
+ efivars->walk_entry = list_first_entry(&efivars->list,
+ struct efivar_entry, list);
+ return 0;
+@@ -656,7 +657,7 @@ static int efi_pstore_close(struct pstor
+ {
+ struct efivars *efivars = psi->data;
+
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ return 0;
+ }
+
+@@ -712,11 +713,12 @@ static int efi_pstore_write(enum pstore_
+ int i, ret = 0;
+ u64 storage_space, remaining_space, max_variable_size;
+ efi_status_t status = EFI_NOT_FOUND;
++ unsigned long flags;
+
+ sprintf(stub_name, "dump-type%u-%u-", type, part);
+ sprintf(name, "%s%lu", stub_name, get_seconds());
+
+- spin_lock(&efivars->lock);
++ spin_lock_irqsave(&efivars->lock, flags);
+
+ /*
+ * Check if there is a space enough to log.
+@@ -728,7 +730,7 @@ static int efi_pstore_write(enum pstore_
+ &remaining_space,
+ &max_variable_size);
+ if (status || remaining_space < size + DUMP_NAME_LEN * 2) {
+- spin_unlock(&efivars->lock);
++ spin_unlock_irqrestore(&efivars->lock, flags);
+ *id = part;
+ return -ENOSPC;
+ }
+@@ -769,7 +771,7 @@ static int efi_pstore_write(enum pstore_
+ efivars->ops->set_variable(efi_name, &vendor, PSTORE_EFI_ATTRIBUTES,
+ size, psi->buf);
+
+- spin_unlock(&efivars->lock);
++ spin_unlock_irqrestore(&efivars->lock, flags);
+
+ if (found)
+ efivar_unregister(found);
+@@ -853,7 +855,7 @@ static ssize_t efivar_create(struct file
+ return -EINVAL;
+ }
+
+- spin_lock(&efivars->lock);
++ spin_lock_irq(&efivars->lock);
+
+ /*
+ * Does this variable already exist?
+@@ -871,7 +873,7 @@ static ssize_t efivar_create(struct file
+ }
+ }
+ if (found) {
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ return -EINVAL;
+ }
+
+@@ -885,10 +887,10 @@ static ssize_t efivar_create(struct file
+ if (status != EFI_SUCCESS) {
+ printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
+ status);
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ return -EIO;
+ }
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+
+ /* Create the entry in sysfs. Locking is not required here */
+ status = efivar_create_sysfs_entry(efivars,
+@@ -916,7 +918,7 @@ static ssize_t efivar_delete(struct file
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+- spin_lock(&efivars->lock);
++ spin_lock_irq(&efivars->lock);
+
+ /*
+ * Does this variable already exist?
+@@ -934,7 +936,7 @@ static ssize_t efivar_delete(struct file
+ }
+ }
+ if (!found) {
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ return -EINVAL;
+ }
+ /* force the Attributes/DataSize to 0 to ensure deletion */
+@@ -950,12 +952,12 @@ static ssize_t efivar_delete(struct file
+ if (status != EFI_SUCCESS) {
+ printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
+ status);
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ return -EIO;
+ }
+ list_del(&search_efivar->list);
+ /* We need to release this lock before unregistering. */
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ efivar_unregister(search_efivar);
+
+ /* It's dead Jim.... */
+@@ -1110,9 +1112,9 @@ efivar_create_sysfs_entry(struct efivars
+ kfree(short_name);
+ short_name = NULL;
+
+- spin_lock(&efivars->lock);
++ spin_lock_irq(&efivars->lock);
+ list_add(&new_efivar->list, &efivars->list);
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+
+ return 0;
+ }
+@@ -1181,9 +1183,9 @@ void unregister_efivars(struct efivars *
+ struct efivar_entry *entry, *n;
+
+ list_for_each_entry_safe(entry, n, &efivars->list, list) {
+- spin_lock(&efivars->lock);
++ spin_lock_irq(&efivars->lock);
+ list_del(&entry->list);
+- spin_unlock(&efivars->lock);
++ spin_unlock_irq(&efivars->lock);
+ efivar_unregister(entry);
+ }
+ if (efivars->new_var)
--- /dev/null
+From 80a19debc2f2d398cfa57fae97bc99826748a602 Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sat, 23 Mar 2013 03:49:53 +0000
+Subject: efivars: pstore: Do not check size when erasing variable
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+commit 80a19debc2f2d398cfa57fae97bc99826748a602 upstream.
+
+In 3.2, unlike mainline, efi_pstore_erase() calls efi_pstore_write()
+with a size of 0, as the underlying EFI interface treats a size of 0
+as meaning deletion.
+
+This was not taken into account in my backport of commit d80a361d779a
+'efi_pstore: Check remaining space with QueryVariableInfo() before
+writing data'. The size check should be omitted when erasing.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/firmware/efivars.c | 24 +++++++++++++-----------
+ 1 file changed, 13 insertions(+), 11 deletions(-)
+
+--- a/drivers/firmware/efivars.c
++++ b/drivers/firmware/efivars.c
+@@ -778,19 +778,21 @@ static int efi_pstore_write(enum pstore_
+
+ spin_lock_irqsave(&efivars->lock, flags);
+
+- /*
+- * Check if there is a space enough to log.
+- * size: a size of logging data
+- * DUMP_NAME_LEN * 2: a maximum size of variable name
+- */
++ if (size) {
++ /*
++ * Check if there is a space enough to log.
++ * size: a size of logging data
++ * DUMP_NAME_LEN * 2: a maximum size of variable name
++ */
+
+- status = check_var_size_locked(efivars, PSTORE_EFI_ATTRIBUTES,
+- size + DUMP_NAME_LEN * 2);
++ status = check_var_size_locked(efivars, PSTORE_EFI_ATTRIBUTES,
++ size + DUMP_NAME_LEN * 2);
+
+- if (status) {
+- spin_unlock_irqrestore(&efivars->lock, flags);
+- *id = part;
+- return -ENOSPC;
++ if (status) {
++ spin_unlock_irqrestore(&efivars->lock, flags);
++ *id = part;
++ return -ENOSPC;
++ }
+ }
+
+ for (i = 0; i < DUMP_NAME_LEN; i++)
--- /dev/null
+From 93ed2b137b974b6515f0c847438c7d78a567c1ce Mon Sep 17 00:00:00 2001
+From: Russ Gorby <russ.gorby@intel.com>
+Date: Mon, 13 Aug 2012 13:44:59 +0100
+Subject: n_gsm: avoid accessing freed memory during CMD_FCOFF condition
+
+From: Russ Gorby <russ.gorby@intel.com>
+
+commit b4338e1efc339986cf6c0a3652906e914a86e2d3 upstream.
+
+gsm_data_kick was recently modified to allow messages on the
+tx queue bound for DLCI0 to flow even during FCOFF conditions.
+Unfortunately we introduced a bug discovered by code inspection
+where subsequent list traversers can access freed memory if
+the DLCI0 messages were not all at the head of the list.
+
+Replaced singly linked tx list w/ a list_head and used
+provided interfaces for traversing and deleting members.
+
+Signed-off-by: Russ Gorby <russ.gorby@intel.com>
+Tested-by: Yin, Fengwei <fengwei.yin@intel.com>
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/n_gsm.c | 40 +++++++++++++---------------------------
+ 1 file changed, 13 insertions(+), 27 deletions(-)
+
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -108,7 +108,7 @@ struct gsm_mux_net {
+ */
+
+ struct gsm_msg {
+- struct gsm_msg *next;
++ struct list_head list;
+ u8 addr; /* DLCI address + flags */
+ u8 ctrl; /* Control byte + flags */
+ unsigned int len; /* Length of data block (can be zero) */
+@@ -245,8 +245,7 @@ struct gsm_mux {
+ unsigned int tx_bytes; /* TX data outstanding */
+ #define TX_THRESH_HI 8192
+ #define TX_THRESH_LO 2048
+- struct gsm_msg *tx_head; /* Pending data packets */
+- struct gsm_msg *tx_tail;
++ struct list_head tx_list; /* Pending data packets */
+
+ /* Control messages */
+ struct timer_list t2_timer; /* Retransmit timer for commands */
+@@ -663,7 +662,7 @@ static struct gsm_msg *gsm_data_alloc(st
+ m->len = len;
+ m->addr = addr;
+ m->ctrl = ctrl;
+- m->next = NULL;
++ INIT_LIST_HEAD(&m->list);
+ return m;
+ }
+
+@@ -681,16 +680,13 @@ static struct gsm_msg *gsm_data_alloc(st
+
+ static void gsm_data_kick(struct gsm_mux *gsm)
+ {
+- struct gsm_msg *msg = gsm->tx_head;
+- struct gsm_msg *free_msg;
++ struct gsm_msg *msg, *nmsg;
+ int len;
+ int skip_sof = 0;
+
+- while (msg) {
+- if (gsm->constipated && msg->addr) {
+- msg = msg->next;
++ list_for_each_entry_safe(msg, nmsg, &gsm->tx_list, list) {
++ if (gsm->constipated && msg->addr)
+ continue;
+- }
+ if (gsm->encoding != 0) {
+ gsm->txframe[0] = GSM1_SOF;
+ len = gsm_stuff_frame(msg->data,
+@@ -718,14 +714,9 @@ static void gsm_data_kick(struct gsm_mux
+ burst */
+ skip_sof = 1;
+
+- if (gsm->tx_head == msg)
+- gsm->tx_head = msg->next;
+- free_msg = msg;
+- msg = msg->next;
+- kfree(free_msg);
++ list_del(&msg->list);
++ kfree(msg);
+ }
+- if (!gsm->tx_head)
+- gsm->tx_tail = NULL;
+ }
+
+ /**
+@@ -774,11 +765,7 @@ static void __gsm_data_queue(struct gsm_
+ msg->data = dp;
+
+ /* Add to the actual output queue */
+- if (gsm->tx_tail)
+- gsm->tx_tail->next = msg;
+- else
+- gsm->tx_head = msg;
+- gsm->tx_tail = msg;
++ list_add_tail(&msg->list, &gsm->tx_list);
+ gsm->tx_bytes += msg->len;
+ gsm_data_kick(gsm);
+ }
+@@ -2052,7 +2039,7 @@ void gsm_cleanup_mux(struct gsm_mux *gsm
+ {
+ int i;
+ struct gsm_dlci *dlci = gsm->dlci[0];
+- struct gsm_msg *txq;
++ struct gsm_msg *txq, *utxq;
+ struct gsm_control *gc;
+
+ gsm->dead = 1;
+@@ -2087,11 +2074,9 @@ void gsm_cleanup_mux(struct gsm_mux *gsm
+ if (gsm->dlci[i])
+ gsm_dlci_release(gsm->dlci[i]);
+ /* Now wipe the queues */
+- for (txq = gsm->tx_head; txq != NULL; txq = gsm->tx_head) {
+- gsm->tx_head = txq->next;
++ list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list)
+ kfree(txq);
+- }
+- gsm->tx_tail = NULL;
++ INIT_LIST_HEAD(&gsm->tx_list);
+ }
+ EXPORT_SYMBOL_GPL(gsm_cleanup_mux);
+
+@@ -2202,6 +2187,7 @@ struct gsm_mux *gsm_alloc_mux(void)
+ }
+ spin_lock_init(&gsm->lock);
+ kref_init(&gsm->ref);
++ INIT_LIST_HEAD(&gsm->tx_list);
+
+ gsm->t1 = T1;
+ gsm->t2 = T2;
--- /dev/null
+From 6e9b3851b52f170abd7e7cabd01f34f327626c1c Mon Sep 17 00:00:00 2001
+From: Frederic Berat <fredericx.berat@intel.com>
+Date: Mon, 13 Aug 2012 13:43:58 +0100
+Subject: n_gsm : Flow control handling in Mux driver
+
+From: Frederic Berat <fredericx.berat@intel.com>
+
+commit c01af4fec2c8f303d6b3354d44308d9e6bef8026 upstream.
+
+- Correcting handling of FCon/FCoff in order to respect 27.010 spec
+- Consider FCon/off will overide all dlci flow control except for
+ dlci0 as we must be able to send control frames.
+- Dlci constipated handling according to FC, RTC and RTR values.
+- Modifying gsm_dlci_data_kick and gsm_dlci_data_sweep according
+ to dlci constipated value
+
+Signed-off-by: Frederic Berat <fredericx.berat@intel.com>
+Signed-off-by: Russ Gorby <russ.gorby@intel.com>
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/n_gsm.c | 79 +++++++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 57 insertions(+), 22 deletions(-)
+
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -673,6 +673,8 @@ static struct gsm_msg *gsm_data_alloc(st
+ *
+ * The tty device has called us to indicate that room has appeared in
+ * the transmit queue. Ram more data into the pipe if we have any
++ * If we have been flow-stopped by a CMD_FCOFF, then we can only
++ * send messages on DLCI0 until CMD_FCON
+ *
+ * FIXME: lock against link layer control transmissions
+ */
+@@ -680,15 +682,19 @@ static struct gsm_msg *gsm_data_alloc(st
+ static void gsm_data_kick(struct gsm_mux *gsm)
+ {
+ struct gsm_msg *msg = gsm->tx_head;
++ struct gsm_msg *free_msg;
+ int len;
+ int skip_sof = 0;
+
+- /* FIXME: We need to apply this solely to data messages */
+- if (gsm->constipated)
+- return;
+-
+- while (gsm->tx_head != NULL) {
+- msg = gsm->tx_head;
++ while (msg) {
++ if (gsm->constipated && msg->addr) {
++ msg = msg->next;
++ continue;
++ }
++ if (gsm->dlci[msg->addr]->constipated) {
++ msg = msg->next;
++ continue;
++ }
+ if (gsm->encoding != 0) {
+ gsm->txframe[0] = GSM1_SOF;
+ len = gsm_stuff_frame(msg->data,
+@@ -711,15 +717,19 @@ static void gsm_data_kick(struct gsm_mux
+ len - skip_sof) < 0)
+ break;
+ /* FIXME: Can eliminate one SOF in many more cases */
+- gsm->tx_head = msg->next;
+- if (gsm->tx_head == NULL)
+- gsm->tx_tail = NULL;
+ gsm->tx_bytes -= msg->len;
+- kfree(msg);
+ /* For a burst of frames skip the extra SOF within the
+ burst */
+ skip_sof = 1;
++
++ if (gsm->tx_head == msg)
++ gsm->tx_head = msg->next;
++ free_msg = msg;
++ msg = msg->next;
++ kfree(free_msg);
+ }
++ if (!gsm->tx_head)
++ gsm->tx_tail = NULL;
+ }
+
+ /**
+@@ -738,6 +748,8 @@ static void __gsm_data_queue(struct gsm_
+ u8 *dp = msg->data;
+ u8 *fcs = dp + msg->len;
+
++ WARN_ONCE(dlci->constipated, "%s: queueing from a constipated DLCI",
++ __func__);
+ /* Fill in the header */
+ if (gsm->encoding == 0) {
+ if (msg->len < 128)
+@@ -947,6 +959,9 @@ static void gsm_dlci_data_sweep(struct g
+ break;
+ dlci = gsm->dlci[i];
+ if (dlci == NULL || dlci->constipated) {
++ if (dlci && (debug & 0x20))
++ pr_info("%s: DLCI %d is constipated",
++ __func__, i);
+ i++;
+ continue;
+ }
+@@ -976,6 +991,13 @@ static void gsm_dlci_data_kick(struct gs
+ unsigned long flags;
+ int sweep;
+
++ if (dlci->constipated) {
++ if (debug & 0x20)
++ pr_info("%s: DLCI %d is constipated",
++ __func__, dlci->addr);
++ return;
++ }
++
+ spin_lock_irqsave(&dlci->gsm->tx_lock, flags);
+ /* If we have nothing running then we need to fire up */
+ sweep = (dlci->gsm->tx_bytes < TX_THRESH_LO);
+@@ -1033,6 +1055,7 @@ static void gsm_process_modem(struct tty
+ {
+ int mlines = 0;
+ u8 brk = 0;
++ int fc;
+
+ /* The modem status command can either contain one octet (v.24 signals)
+ or two octets (v.24 signals + break signals). The length field will
+@@ -1044,19 +1067,27 @@ static void gsm_process_modem(struct tty
+ else {
+ brk = modem & 0x7f;
+ modem = (modem >> 7) & 0x7f;
+- };
++ }
+
+ /* Flow control/ready to communicate */
+- if (modem & MDM_FC) {
++ fc = (modem & MDM_FC) || !(modem & MDM_RTR);
++ if (fc && !dlci->constipated) {
++ if (debug & 0x20)
++ pr_info("%s: DLCI %d START constipated (tx_bytes=%d)",
++ __func__, dlci->addr, dlci->gsm->tx_bytes);
+ /* Need to throttle our output on this device */
+ dlci->constipated = 1;
+- }
+- if (modem & MDM_RTC) {
+- mlines |= TIOCM_DSR | TIOCM_DTR;
++ } else if (!fc && dlci->constipated) {
++ if (debug & 0x20)
++ pr_info("%s: DLCI %d END constipated (tx_bytes=%d)",
++ __func__, dlci->addr, dlci->gsm->tx_bytes);
+ dlci->constipated = 0;
+ gsm_dlci_data_kick(dlci);
+ }
++
+ /* Map modem bits */
++ if (modem & MDM_RTC)
++ mlines |= TIOCM_DSR | TIOCM_DTR;
+ if (modem & MDM_RTR)
+ mlines |= TIOCM_RTS | TIOCM_CTS;
+ if (modem & MDM_IC)
+@@ -1225,19 +1256,23 @@ static void gsm_control_message(struct g
+ gsm_control_reply(gsm, CMD_TEST, data, clen);
+ break;
+ case CMD_FCON:
+- /* Modem wants us to STFU */
+- gsm->constipated = 1;
+- gsm_control_reply(gsm, CMD_FCON, NULL, 0);
+- break;
+- case CMD_FCOFF:
+ /* Modem can accept data again */
++ if (debug & 0x20)
++ pr_info("%s: GSM END constipation", __func__);
+ gsm->constipated = 0;
+- gsm_control_reply(gsm, CMD_FCOFF, NULL, 0);
++ gsm_control_reply(gsm, CMD_FCON, NULL, 0);
+ /* Kick the link in case it is idling */
+ spin_lock_irqsave(&gsm->tx_lock, flags);
+ gsm_data_kick(gsm);
+ spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ break;
++ case CMD_FCOFF:
++ /* Modem wants us to STFU */
++ if (debug & 0x20)
++ pr_info("%s: GSM START constipation", __func__);
++ gsm->constipated = 1;
++ gsm_control_reply(gsm, CMD_FCOFF, NULL, 0);
++ break;
+ case CMD_MSC:
+ /* Out of band modem line change indicator for a DLCI */
+ gsm_control_modem(gsm, data, clen);
+@@ -2306,7 +2341,7 @@ static void gsmld_receive_buf(struct tty
+ gsm->error(gsm, *dp, flags);
+ break;
+ default:
+- WARN_ONCE("%s: unknown flag %d\n",
++ WARN_ONCE(1, "%s: unknown flag %d\n",
+ tty_name(tty, buf), flags);
+ break;
+ }
--- /dev/null
+From 0afc4d3b3b1320437cdcc8a290ba9dd9dabe35c0 Mon Sep 17 00:00:00 2001
+From: Russ Gorby <russ.gorby@intel.com>
+Date: Mon, 13 Aug 2012 13:45:15 +0100
+Subject: n_gsm: replace kfree_skb w/ appropriate dev_* versions
+
+From: Russ Gorby <russ.gorby@intel.com>
+
+commit 329e56780e514a7ab607bcb51a52ab0dc2669414 upstream.
+
+Drivers are supposed to use the dev_* versions of the kfree_skb
+interfaces. In a couple of cases we were called with IRQs
+disabled as well which kfree_skb() does not expect.
+
+Replaced kfree_skb calls w/ dev_kfree_skb and dev_kfree_skb_any
+
+Signed-off-by: Russ Gorby <russ.gorby@intel.com>
+Tested-by: Yin, Fengwei <fengwei.yin@intel.com>
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/n_gsm.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -879,7 +879,7 @@ static int gsm_dlci_data_output_framed(s
+ if (len > gsm->mtu) {
+ if (dlci->adaption == 3) {
+ /* Over long frame, bin it */
+- kfree_skb(dlci->skb);
++ dev_kfree_skb_any(dlci->skb);
+ dlci->skb = NULL;
+ return 0;
+ }
+@@ -908,7 +908,7 @@ static int gsm_dlci_data_output_framed(s
+ skb_pull(dlci->skb, len);
+ __gsm_data_queue(dlci, msg);
+ if (last) {
+- kfree_skb(dlci->skb);
++ dev_kfree_skb_any(dlci->skb);
+ dlci->skb = NULL;
+ }
+ return size;
+@@ -1688,7 +1688,7 @@ static void gsm_dlci_free(struct kref *r
+ dlci->gsm->dlci[dlci->addr] = NULL;
+ kfifo_free(dlci->fifo);
+ while ((dlci->skb = skb_dequeue(&dlci->skb_list)))
+- kfree_skb(dlci->skb);
++ dev_kfree_skb(dlci->skb);
+ kfree(dlci);
+ }
+
+@@ -2039,7 +2039,7 @@ void gsm_cleanup_mux(struct gsm_mux *gsm
+ {
+ int i;
+ struct gsm_dlci *dlci = gsm->dlci[0];
+- struct gsm_msg *txq, *utxq;
++ struct gsm_msg *txq, *ntxq;
+ struct gsm_control *gc;
+
+ gsm->dead = 1;
--- /dev/null
+From 6d0d3f3aca8f6ec0cd91d062abab0196905a9352 Mon Sep 17 00:00:00 2001
+From: Oleg Nesterov <oleg@redhat.com>
+Date: Fri, 3 Aug 2012 17:31:46 +0200
+Subject: ptrace/x86: Introduce set_task_blockstep() helper
+
+From: Oleg Nesterov <oleg@redhat.com>
+
+commit 848e8f5f0ad3169560c516fff6471be65f76e69f upstream.
+
+No functional changes, preparation for the next fix and for uprobes
+single-step fixes.
+
+Move the code playing with TIF_BLOCKSTEP/DEBUGCTLMSR_BTF into the
+new helper, set_task_blockstep().
+
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/step.c | 41 +++++++++++++++++++++--------------------
+ 1 file changed, 21 insertions(+), 20 deletions(-)
+
+--- a/arch/x86/kernel/step.c
++++ b/arch/x86/kernel/step.c
+@@ -157,6 +157,21 @@ static int enable_single_step(struct tas
+ return 1;
+ }
+
++static void set_task_blockstep(struct task_struct *task, bool on)
++{
++ unsigned long debugctl;
++
++ debugctl = get_debugctlmsr();
++ if (on) {
++ debugctl |= DEBUGCTLMSR_BTF;
++ set_tsk_thread_flag(task, TIF_BLOCKSTEP);
++ } else {
++ debugctl &= ~DEBUGCTLMSR_BTF;
++ clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
++ }
++ update_debugctlmsr(debugctl);
++}
++
+ /*
+ * Enable single or block step.
+ */
+@@ -169,19 +184,10 @@ static void enable_step(struct task_stru
+ * So no one should try to use debugger block stepping in a program
+ * that uses user-mode single stepping itself.
+ */
+- if (enable_single_step(child) && block) {
+- unsigned long debugctl = get_debugctlmsr();
+-
+- debugctl |= DEBUGCTLMSR_BTF;
+- update_debugctlmsr(debugctl);
+- set_tsk_thread_flag(child, TIF_BLOCKSTEP);
+- } else if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) {
+- unsigned long debugctl = get_debugctlmsr();
+-
+- debugctl &= ~DEBUGCTLMSR_BTF;
+- update_debugctlmsr(debugctl);
+- clear_tsk_thread_flag(child, TIF_BLOCKSTEP);
+- }
++ if (enable_single_step(child) && block)
++ set_task_blockstep(child, true);
++ else if (test_tsk_thread_flag(child, TIF_BLOCKSTEP))
++ set_task_blockstep(child, false);
+ }
+
+ void user_enable_single_step(struct task_struct *child)
+@@ -199,13 +205,8 @@ void user_disable_single_step(struct tas
+ /*
+ * Make sure block stepping (BTF) is disabled.
+ */
+- if (test_tsk_thread_flag(child, TIF_BLOCKSTEP)) {
+- unsigned long debugctl = get_debugctlmsr();
+-
+- debugctl &= ~DEBUGCTLMSR_BTF;
+- update_debugctlmsr(debugctl);
+- clear_tsk_thread_flag(child, TIF_BLOCKSTEP);
+- }
++ if (test_tsk_thread_flag(child, TIF_BLOCKSTEP))
++ set_task_blockstep(child, false);
+
+ /* Always clear TIF_SINGLESTEP... */
+ clear_tsk_thread_flag(child, TIF_SINGLESTEP);
--- /dev/null
+From 667958738244e5be2cb1e05ab1f2a112c52e1c64 Mon Sep 17 00:00:00 2001
+From: Oleg Nesterov <oleg@redhat.com>
+Date: Sat, 11 Aug 2012 18:06:42 +0200
+Subject: ptrace/x86: Partly fix set_task_blockstep()->update_debugctlmsr() logic
+
+From: Oleg Nesterov <oleg@redhat.com>
+
+commit 95cf00fa5d5e2a200a2c044c84bde8389a237e02 upstream.
+
+Afaics the usage of update_debugctlmsr() and TIF_BLOCKSTEP in
+step.c was always very wrong.
+
+1. update_debugctlmsr() was simply unneeded. The child sleeps
+ TASK_TRACED, __switch_to_xtra(next_p => child) should notice
+ TIF_BLOCKSTEP and set/clear DEBUGCTLMSR_BTF after resume if
+ needed.
+
+2. It is wrong. The state of DEBUGCTLMSR_BTF bit in CPU register
+ should always match the state of current's TIF_BLOCKSTEP bit.
+
+3. Even get_debugctlmsr() + update_debugctlmsr() itself does not
+ look right. Irq can change other bits in MSR_IA32_DEBUGCTLMSR
+ register or the caller can be preempted in between.
+
+4. It is not safe to play with TIF_BLOCKSTEP if task != current.
+ DEBUGCTLMSR_BTF and TIF_BLOCKSTEP should always match each
+ other if the task is running. The tracee is stopped but it
+ can be SIGKILL'ed right before set/clear_tsk_thread_flag().
+
+However, now that uprobes uses user_enable_single_step(current)
+we can't simply remove update_debugctlmsr(). So this patch adds
+the additional "task == current" check and disables irqs to avoid
+the race with interrupts/preemption.
+
+Unfortunately this patch doesn't solve the last problem, we need
+another fix. Probably we should teach ptrace_stop() to set/clear
+single/block stepping after resume.
+
+And afaics there is yet another problem: perf can play with
+MSR_IA32_DEBUGCTLMSR from nmi, this obviously means that even
+__switch_to_xtra() has problems.
+
+Signed-off-by: Oleg Nesterov <oleg@redhat.com>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/step.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/kernel/step.c
++++ b/arch/x86/kernel/step.c
+@@ -161,6 +161,16 @@ static void set_task_blockstep(struct ta
+ {
+ unsigned long debugctl;
+
++ /*
++ * Ensure irq/preemption can't change debugctl in between.
++ * Note also that both TIF_BLOCKSTEP and debugctl should
++ * be changed atomically wrt preemption.
++ * FIXME: this means that set/clear TIF_BLOCKSTEP is simply
++ * wrong if task != current, SIGKILL can wakeup the stopped
++ * tracee and set/clear can play with the running task, this
++ * can confuse the next __switch_to_xtra().
++ */
++ local_irq_disable();
+ debugctl = get_debugctlmsr();
+ if (on) {
+ debugctl |= DEBUGCTLMSR_BTF;
+@@ -169,7 +179,9 @@ static void set_task_blockstep(struct ta
+ debugctl &= ~DEBUGCTLMSR_BTF;
+ clear_tsk_thread_flag(task, TIF_BLOCKSTEP);
+ }
+- update_debugctlmsr(debugctl);
++ if (task == current)
++ update_debugctlmsr(debugctl);
++ local_irq_enable();
+ }
+
+ /*
alsa-hda-conexant-correct-vendor-ids-for-new-codecs.patch
alsa-hda-add-conexant-cx20755-20756-20757-codec-ids.patch
alsa-hda-add-support-for-cx20952.patch
+tty-serial-imx-don-t-reinit-clock-in-imx_setup_ufcr.patch
+x86-build-icc-remove-uninitialized_var-from-compiler-intel.h.patch
+x86-build-pass-in-additional-mno-mmx-mno-sse-options.patch
+x86-apic-disable-i-o-apic-before-shutdown-of-the-local-apic.patch
+x86-fix-build-error-and-kconfig-for-ia32_emulation-and-binfmt.patch
+n_gsm-flow-control-handling-in-mux-driver.patch
+char-n_gsm-remove-message-filtering-for-contipated-dlci.patch
+n_gsm-avoid-accessing-freed-memory-during-cmd_fcoff-condition.patch
+n_gsm-replace-kfree_skb-w-appropriate-dev_-versions.patch
+x86-get_unmapped_area-access-mmap_legacy_base-through-mm_struct-member.patch
+ptrace-x86-introduce-set_task_blockstep-helper.patch
+ptrace-x86-partly-fix-set_task_blockstep-update_debugctlmsr-logic.patch
+x86-sandy-bridge-mark-arrays-in-__init-functions-as-__initconst.patch
+efi_pstore-check-remaining-space-with-queryvariableinfo-before-writing-data.patch
+efivars-disable-external-interrupt-while-holding-efivars-lock.patch
+efi-be-more-paranoid-about-available-space-when-creating-variables.patch
+efivars-pstore-do-not-check-size-when-erasing-variable.patch
+efivars-allow-disabling-use-as-a-pstore-backend.patch
--- /dev/null
+From da75c41ed3cf1fc577b24dc87559bd32e27ebc8b Mon Sep 17 00:00:00 2001
+From: Dirk Behme <dirk.behme@de.bosch.com>
+Date: Fri, 31 Aug 2012 10:02:47 +0200
+Subject: tty: serial: imx: don't reinit clock in imx_setup_ufcr()
+
+From: Dirk Behme <dirk.behme@de.bosch.com>
+
+commit 7be0670f7b9198382938a03ff3db7f47ef6b4780 upstream.
+
+Remove the clock configuration from imx_setup_ufcr(). This
+isn't needed here and will cause garbage output if done.
+
+To be be sure that we only touch the bits we want (TXTL and RXTL)
+we have to mask out all other bits of the UFCR register. Add
+one non-existing bit macro for this, too (bit 6, DCEDTE on i.MX6).
+
+Signed-off-by: Dirk Behme <dirk.behme@de.bosch.com>
+CC: Shawn Guo <shawn.guo@linaro.org>
+CC: Sascha Hauer <s.hauer@pengutronix.de>
+CC: Troy Kisky <troy.kisky@boundarydevices.com>
+CC: Xinyu Chen <xinyu.chen@freescale.com>
+Acked-by: Shawn Guo <shawn.guo@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[bwh: Backported to 3.2: deleted code in imx_setup_ufcr() refers to
+ sport->clk not sport->clk_per]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/imx.c | 18 ++++--------------
+ 1 file changed, 4 insertions(+), 14 deletions(-)
+
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -131,6 +131,7 @@
+ #define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */
+ #define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */
+ #define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */
++#define UFCR_DCEDTE (1<<6) /* DCE/DTE mode select */
+ #define UFCR_RFDIV (7<<7) /* Reference freq divider mask */
+ #define UFCR_RFDIV_REG(x) (((x) < 7 ? 6 - (x) : 6) << 7)
+ #define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */
+@@ -666,22 +667,11 @@ static void imx_break_ctl(struct uart_po
+ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
+ {
+ unsigned int val;
+- unsigned int ufcr_rfdiv;
+-
+- /* set receiver / transmitter trigger level.
+- * RFDIV is set such way to satisfy requested uartclk value
+- */
+- val = TXTL << 10 | RXTL;
+- ufcr_rfdiv = (clk_get_rate(sport->clk) + sport->port.uartclk / 2)
+- / sport->port.uartclk;
+-
+- if(!ufcr_rfdiv)
+- ufcr_rfdiv = 1;
+-
+- val |= UFCR_RFDIV_REG(ufcr_rfdiv);
+
++ /* set receiver / transmitter trigger level */
++ val = readl(sport->port.membase + UFCR) & (UFCR_RFDIV | UFCR_DCEDTE);
++ val |= TXTL << UFCR_TXTL_SHF | RXTL;
+ writel(val, sport->port.membase + UFCR);
+-
+ return 0;
+ }
+
--- /dev/null
+From d8c3245c97490cb68ceaa983b5fce19055b4e331 Mon Sep 17 00:00:00 2001
+From: Fenghua Yu <fenghua.yu@intel.com>
+Date: Wed, 23 Oct 2013 18:30:12 -0700
+Subject: x86/apic: Disable I/O APIC before shutdown of the local APIC
+
+From: Fenghua Yu <fenghua.yu@intel.com>
+
+commit 522e66464467543c0d88d023336eec4df03ad40b upstream.
+
+In reboot and crash path, when we shut down the local APIC, the I/O APIC is
+still active. This may cause issues because external interrupts
+can still come in and disturb the local APIC during shutdown process.
+
+To quiet external interrupts, disable I/O APIC before shutdown local APIC.
+
+Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
+Link: http://lkml.kernel.org/r/1382578212-4677-1-git-send-email-fenghua.yu@intel.com
+[ I suppose the 'issue' is a hang during shutdown. It's a fine change nevertheless. ]
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+[bwh: Backported to 3.2: adjust context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/crash.c | 2 +-
+ arch/x86/kernel/reboot.c | 11 +++++++----
+ 2 files changed, 8 insertions(+), 5 deletions(-)
+
+--- a/arch/x86/kernel/crash.c
++++ b/arch/x86/kernel/crash.c
+@@ -95,10 +95,10 @@ void native_machine_crash_shutdown(struc
+ cpu_emergency_vmxoff();
+ cpu_emergency_svm_disable();
+
+- lapic_shutdown();
+ #if defined(CONFIG_X86_IO_APIC)
+ disable_IO_APIC();
+ #endif
++ lapic_shutdown();
+ #ifdef CONFIG_HPET_TIMER
+ hpet_disable();
+ #endif
+--- a/arch/x86/kernel/reboot.c
++++ b/arch/x86/kernel/reboot.c
+@@ -668,6 +668,13 @@ void native_machine_shutdown(void)
+
+ /* The boot cpu is always logical cpu 0 */
+ int reboot_cpu_id = 0;
++#endif
++
++#ifdef CONFIG_X86_IO_APIC
++ disable_IO_APIC();
++#endif
++
++#ifdef CONFIG_SMP
+
+ #ifdef CONFIG_X86_32
+ /* See if there has been given a command line override */
+@@ -691,10 +698,6 @@ void native_machine_shutdown(void)
+
+ lapic_shutdown();
+
+-#ifdef CONFIG_X86_IO_APIC
+- disable_IO_APIC();
+-#endif
+-
+ #ifdef CONFIG_HPET_TIMER
+ hpet_disable();
+ #endif
--- /dev/null
+From 4fe644c42cb5980bfa920fdf9f1d1bc306328c52 Mon Sep 17 00:00:00 2001
+From: "H. Peter Anvin" <hpa@linux.intel.com>
+Date: Tue, 10 Dec 2013 14:56:06 -0800
+Subject: x86, build, icc: Remove uninitialized_var() from compiler-intel.h
+
+From: "H. Peter Anvin" <hpa@linux.intel.com>
+
+commit 503cf95c061a0551eb684da364509297efbe55d9 upstream.
+
+When compiling with icc, <linux/compiler-gcc.h> ends up included
+because the icc environment defines __GNUC__. Thus, we neither need
+nor want to have this macro defined in both compiler-gcc.h and
+compiler-intel.h, and the fact that they are inconsistent just makes
+the compiler spew warnings.
+
+Reported-by: Sunil K. Pandey <sunil.k.pandey@intel.com>
+Cc: Kevin B. Smith <kevin.b.smith@intel.com>
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Link: http://lkml.kernel.org/n/tip-0mbwou1zt7pafij09b897lg3@git.kernel.org
+[bwh: Backported to 3.2: adjust context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/compiler-intel.h | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/include/linux/compiler-intel.h
++++ b/include/linux/compiler-intel.h
+@@ -27,5 +27,3 @@
+ #define __must_be_array(a) 0
+
+ #endif
+-
+-#define uninitialized_var(x) x
--- /dev/null
+From 612e9718fa791e611c17e1949841766b122a817b Mon Sep 17 00:00:00 2001
+From: "H. Peter Anvin" <hpa@linux.intel.com>
+Date: Mon, 9 Dec 2013 15:43:38 -0800
+Subject: x86, build: Pass in additional -mno-mmx, -mno-sse options
+
+From: "H. Peter Anvin" <hpa@linux.intel.com>
+
+commit 8b3b005d675726e38bc504d2e35a991e55819155 upstream.
+
+In checkin
+
+ 5551a34e5aea x86-64, build: Always pass in -mno-sse
+
+we unconditionally added -mno-sse to the main build, to keep newer
+compilers from generating SSE instructions from autovectorization.
+However, this did not extend to the special environments
+(arch/x86/boot, arch/x86/boot/compressed, and arch/x86/realmode/rm).
+Add -mno-sse to the compiler command line for these environments, and
+add -mno-mmx to all the environments as well, as we don't want a
+compiler to generate MMX code either.
+
+This patch also removes a $(cc-option) call for -m32, since we have
+long since stopped supporting compilers too old for the -m32 option,
+and in fact hardcode it in other places in the Makefiles.
+
+Reported-by: Kevin B. Smith <kevin.b.smith@intel.com>
+Cc: Sunil K. Pandey <sunil.k.pandey@intel.com>
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Cc: H. J. Lu <hjl.tools@gmail.com>
+Link: http://lkml.kernel.org/n/tip-j21wzqv790q834n7yc6g80j1@git.kernel.org
+[bwh: Backported to 3.2:
+ - Drop changes to arch/x86/Makefile, which sets these flags earlier
+ - Adjust context
+ - Drop changes to arch/x86/realmode/rm/Makefile which doesn't exist]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/boot/Makefile | 6 +++---
+ arch/x86/boot/compressed/Makefile | 1 +
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+--- a/arch/x86/boot/Makefile
++++ b/arch/x86/boot/Makefile
+@@ -52,18 +52,18 @@ $(obj)/cpustr.h: $(obj)/mkcpustr FORCE
+
+ # How to compile the 16-bit code. Note we always compile for -march=i386,
+ # that way we can complain to the user if the CPU is insufficient.
+-KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \
++KBUILD_CFLAGS := $(LINUXINCLUDE) -m32 -g -Os -D_SETUP -D__KERNEL__ \
+ -DDISABLE_BRANCH_PROFILING \
+ -Wall -Wstrict-prototypes \
+ -march=i386 -mregparm=3 \
+ -include $(srctree)/$(src)/code16gcc.h \
+ -fno-strict-aliasing -fomit-frame-pointer \
++ -mno-mmx -mno-sse \
+ $(call cc-option, -ffreestanding) \
+ $(call cc-option, -fno-toplevel-reorder,\
+- $(call cc-option, -fno-unit-at-a-time)) \
++ $(call cc-option, -fno-unit-at-a-time)) \
+ $(call cc-option, -fno-stack-protector) \
+ $(call cc-option, -mpreferred-stack-boundary=2)
+-KBUILD_CFLAGS += $(call cc-option, -m32)
+ KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__ASSEMBLY__
+ GCOV_PROFILE := n
+
+--- a/arch/x86/boot/compressed/Makefile
++++ b/arch/x86/boot/compressed/Makefile
+@@ -12,6 +12,7 @@ KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFIL
+ cflags-$(CONFIG_X86_32) := -march=i386
+ cflags-$(CONFIG_X86_64) := -mcmodel=small
+ KBUILD_CFLAGS += $(cflags-y)
++KBUILD_CFLAGS += -mno-mmx -mno-sse
+ KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
+ KBUILD_CFLAGS += $(call cc-option,-fno-stack-protector)
+
--- /dev/null
+From ea3d15ac86cb9697fdabdc801553171b83b35372 Mon Sep 17 00:00:00 2001
+From: Randy Dunlap <rdunlap@infradead.org>
+Date: Tue, 18 Jun 2013 12:33:40 -0700
+Subject: x86: fix build error and kconfig for ia32_emulation and binfmt
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+commit d1603990ea626668c78527376d9ec084d634202d upstream.
+
+Fix kconfig warning and build errors on x86_64 by selecting BINFMT_ELF
+when COMPAT_BINFMT_ELF is being selected.
+
+warning: (IA32_EMULATION) selects COMPAT_BINFMT_ELF which has unmet direct dependencies (COMPAT && BINFMT_ELF)
+
+fs/built-in.o: In function `elf_core_dump':
+compat_binfmt_elf.c:(.text+0x3e093): undefined reference to `elf_core_extra_phdrs'
+compat_binfmt_elf.c:(.text+0x3ebcd): undefined reference to `elf_core_extra_data_size'
+compat_binfmt_elf.c:(.text+0x3eddd): undefined reference to `elf_core_write_extra_phdrs'
+compat_binfmt_elf.c:(.text+0x3f004): undefined reference to `elf_core_write_extra_data'
+
+[ hpa: This was sent to me for -next but it is a low risk build fix ]
+
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Link: http://lkml.kernel.org/r/51C0B614.5000708@infradead.org
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -2157,6 +2157,7 @@ source "fs/Kconfig.binfmt"
+ config IA32_EMULATION
+ bool "IA32 Emulation"
+ depends on X86_64
++ select BINFMT_ELF
+ select COMPAT_BINFMT_ELF
+ ---help---
+ Include code to run legacy 32-bit programs under a
--- /dev/null
+From ac8905cf6be324c76193debc26042fe7a746f89a Mon Sep 17 00:00:00 2001
+From: Radu Caragea <sinaelgl@gmail.com>
+Date: Wed, 21 Aug 2013 20:55:59 +0300
+Subject: x86 get_unmapped_area: Access mmap_legacy_base through mm_struct member
+
+From: Radu Caragea <sinaelgl@gmail.com>
+
+commit 41aacc1eea645c99edbe8fbcf78a97dc9b862adc upstream.
+
+This is the updated version of df54d6fa5427 ("x86 get_unmapped_area():
+use proper mmap base for bottom-up direction") that only randomizes the
+mmap base address once.
+
+Signed-off-by: Radu Caragea <sinaelgl@gmail.com>
+Reported-and-tested-by: Jeff Shorey <shoreyjeff@gmail.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Michel Lespinasse <walken@google.com>
+Cc: Oleg Nesterov <oleg@redhat.com>
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Adrian Sendroiu <molecula2788@gmail.com>
+Cc: Greg KH <greg@kroah.com>
+Cc: Kamal Mostafa <kamal@canonical.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+[bwh: Backported to 3.2: adjust context]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/sys_x86_64.c | 2 +-
+ arch/x86/mm/mmap.c | 6 ++++--
+ include/linux/mm_types.h | 1 +
+ 3 files changed, 6 insertions(+), 3 deletions(-)
+
+--- a/arch/x86/kernel/sys_x86_64.c
++++ b/arch/x86/kernel/sys_x86_64.c
+@@ -115,7 +115,7 @@ static void find_start_end(unsigned long
+ *begin = new_begin;
+ }
+ } else {
+- *begin = TASK_UNMAPPED_BASE;
++ *begin = current->mm->mmap_legacy_base;
+ *end = TASK_SIZE;
+ }
+ }
+--- a/arch/x86/mm/mmap.c
++++ b/arch/x86/mm/mmap.c
+@@ -112,12 +112,14 @@ static unsigned long mmap_legacy_base(vo
+ */
+ void arch_pick_mmap_layout(struct mm_struct *mm)
+ {
++ mm->mmap_legacy_base = mmap_legacy_base();
++ mm->mmap_base = mmap_base();
++
+ if (mmap_is_legacy()) {
+- mm->mmap_base = mmap_legacy_base();
++ mm->mmap_base = mm->mmap_legacy_base;
+ mm->get_unmapped_area = arch_get_unmapped_area;
+ mm->unmap_area = arch_unmap_area;
+ } else {
+- mm->mmap_base = mmap_base();
+ mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+ mm->unmap_area = arch_unmap_area_topdown;
+ }
+--- a/include/linux/mm_types.h
++++ b/include/linux/mm_types.h
+@@ -306,6 +306,7 @@ struct mm_struct {
+ void (*unmap_area) (struct mm_struct *mm, unsigned long addr);
+ #endif
+ unsigned long mmap_base; /* base of mmap area */
++ unsigned long mmap_legacy_base; /* base of mmap area in bottom-up allocations */
+ unsigned long task_size; /* size of task vm space */
+ unsigned long cached_hole_size; /* if non-zero, the largest hole below free_area_cache */
+ unsigned long free_area_cache; /* first hole of size cached_hole_size or larger */
--- /dev/null
+From 91c90db1aa92a50fa1d7f289502b49ddb46a90d3 Mon Sep 17 00:00:00 2001
+From: "H. Peter Anvin" <hpa@linux.intel.com>
+Date: Sun, 13 Jan 2013 20:36:39 -0800
+Subject: x86/Sandy Bridge: mark arrays in __init functions as __initconst
+
+From: "H. Peter Anvin" <hpa@linux.intel.com>
+
+commit 91c90db1aa92a50fa1d7f289502b49ddb46a90d3 upstream.
+
+commit ab3cd8670e0b3fcde7f029e1503ed3c5138e9571 upstream.
+
+Mark static arrays as __initconst so they get removed when the init
+sections are flushed.
+
+Reported-by: Mathias Krause <minipli@googlemail.com>
+Link: http://lkml.kernel.org/r/75F4BEE6-CB0E-4426-B40B-697451677738@googlemail.com
+Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Cc: Rui Xiang <rui.xiang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/setup.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -625,7 +625,7 @@ static bool __init snb_gfx_workaround_ne
+ #ifdef CONFIG_PCI
+ int i;
+ u16 vendor, devid;
+- static const u16 snb_ids[] = {
++ static const __initconst u16 snb_ids[] = {
+ 0x0102,
+ 0x0112,
+ 0x0122,
+@@ -658,7 +658,7 @@ static bool __init snb_gfx_workaround_ne
+ */
+ static void __init trim_snb_memory(void)
+ {
+- static const unsigned long bad_pages[] = {
++ static const __initconst unsigned long bad_pages[] = {
+ 0x20050000,
+ 0x20110000,
+ 0x20130000,