From: Greg Kroah-Hartman Date: Thu, 5 Jun 2014 00:16:30 +0000 (-0700) Subject: 3.4-stable patches X-Git-Tag: v3.14.6~23 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a739b37f3f3af57b27e7f2d29ab09ef93a9e8acb;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: char-n_gsm-remove-message-filtering-for-contipated-dlci.patch efi-be-more-paranoid-about-available-space-when-creating-variables.patch efi_pstore-check-remaining-space-with-queryvariableinfo-before-writing-data.patch efivars-allow-disabling-use-as-a-pstore-backend.patch efivars-disable-external-interrupt-while-holding-efivars-lock.patch efivars-pstore-do-not-check-size-when-erasing-variable.patch n_gsm-avoid-accessing-freed-memory-during-cmd_fcoff-condition.patch n_gsm-flow-control-handling-in-mux-driver.patch n_gsm-replace-kfree_skb-w-appropriate-dev_-versions.patch ptrace-x86-introduce-set_task_blockstep-helper.patch ptrace-x86-partly-fix-set_task_blockstep-update_debugctlmsr-logic.patch tty-serial-imx-don-t-reinit-clock-in-imx_setup_ufcr.patch x86-apic-disable-i-o-apic-before-shutdown-of-the-local-apic.patch x86-build-icc-remove-uninitialized_var-from-compiler-intel.h.patch x86-build-pass-in-additional-mno-mmx-mno-sse-options.patch x86-fix-build-error-and-kconfig-for-ia32_emulation-and-binfmt.patch x86-get_unmapped_area-access-mmap_legacy_base-through-mm_struct-member.patch x86-sandy-bridge-mark-arrays-in-__init-functions-as-__initconst.patch --- diff --git a/queue-3.4/char-n_gsm-remove-message-filtering-for-contipated-dlci.patch b/queue-3.4/char-n_gsm-remove-message-filtering-for-contipated-dlci.patch new file mode 100644 index 00000000000..75302b9dcad --- /dev/null +++ b/queue-3.4/char-n_gsm-remove-message-filtering-for-contipated-dlci.patch @@ -0,0 +1,112 @@ +From ba3fd3d6cf4a97bcb934614295aa2ee4d2cd6ac9 Mon Sep 17 00:00:00 2001 +From: "samix.lebsir" +Date: Mon, 13 Aug 2012 13:44:22 +0100 +Subject: char: n_gsm: remove message filtering for contipated DLCI + +From: "samix.lebsir" + +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 +Signed-off-by: Alan Cox +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Ben Hutchings +Cc: Rui Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-3.4/efi-be-more-paranoid-about-available-space-when-creating-variables.patch b/queue-3.4/efi-be-more-paranoid-about-available-space-when-creating-variables.patch new file mode 100644 index 00000000000..6ddcb94ad88 --- /dev/null +++ b/queue-3.4/efi-be-more-paranoid-about-available-space-when-creating-variables.patch @@ -0,0 +1,185 @@ +From 7feecf3f2b587e535550bb3e7bf75b2fee06fccf Mon Sep 17 00:00:00 2001 +From: Josh Boyer +Date: Mon, 11 Mar 2013 17:48:53 -0400 +Subject: efi: be more paranoid about available space when creating variables + +From: Josh Boyer + +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 +Signed-off-by: Matt Fleming +[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 +Cc: Rui Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-3.4/efi_pstore-check-remaining-space-with-queryvariableinfo-before-writing-data.patch b/queue-3.4/efi_pstore-check-remaining-space-with-queryvariableinfo-before-writing-data.patch new file mode 100644 index 00000000000..309b32f9fab --- /dev/null +++ b/queue-3.4/efi_pstore-check-remaining-space-with-queryvariableinfo-before-writing-data.patch @@ -0,0 +1,85 @@ +From 316d0bb70f66a2682c19494f2d1fdebfa00de1ac Mon Sep 17 00:00:00 2001 +From: Seiji Aguchi +Date: Wed, 14 Nov 2012 20:25:37 +0000 +Subject: efi_pstore: Check remaining space with QueryVariableInfo() before writing data + +From: Seiji Aguchi + +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 +Acked-by: Mike Waychison +Signed-off-by: Tony Luck +Signed-off-by: Ben Hutchings +Cc: Rui Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + 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 { diff --git a/queue-3.4/efivars-allow-disabling-use-as-a-pstore-backend.patch b/queue-3.4/efivars-allow-disabling-use-as-a-pstore-backend.patch new file mode 100644 index 00000000000..f2da3d47737 --- /dev/null +++ b/queue-3.4/efivars-allow-disabling-use-as-a-pstore-backend.patch @@ -0,0 +1,149 @@ +From ed9dc8ce7a1c8115dba9483a9b51df8b63a2e0ef Mon Sep 17 00:00:00 2001 +From: Seth Forshee +Date: Thu, 7 Mar 2013 11:40:17 -0600 +Subject: efivars: Allow disabling use as a pstore backend + +From: Seth Forshee + +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 +Cc: Josh Boyer +Cc: Matthew Garrett +Cc: Seiji Aguchi +Cc: Tony Luck +Signed-off-by: Matt Fleming +[xr: Backported to 3.4: adjust context] +Signed-off-by: Rui Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + 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: + + ++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); diff --git a/queue-3.4/efivars-disable-external-interrupt-while-holding-efivars-lock.patch b/queue-3.4/efivars-disable-external-interrupt-while-holding-efivars-lock.patch new file mode 100644 index 00000000000..b39a4d4a2bd --- /dev/null +++ b/queue-3.4/efivars-disable-external-interrupt-while-holding-efivars-lock.patch @@ -0,0 +1,229 @@ +From 3b048fc196139b840d79b316405bede9b5d3c4c2 Mon Sep 17 00:00:00 2001 +From: Josh Boyer +Date: Mon, 11 Mar 2013 17:47:42 -0400 +Subject: efivars: Disable external interrupt while holding efivars->lock + +From: Josh Boyer + +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 +Acked-by: Mike Waychison +Acked-by: Matt Fleming +Signed-off-by: Tony Luck +[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 +Cc: Rui Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + 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) diff --git a/queue-3.4/efivars-pstore-do-not-check-size-when-erasing-variable.patch b/queue-3.4/efivars-pstore-do-not-check-size-when-erasing-variable.patch new file mode 100644 index 00000000000..7d3b87f3641 --- /dev/null +++ b/queue-3.4/efivars-pstore-do-not-check-size-when-erasing-variable.patch @@ -0,0 +1,60 @@ +From 80a19debc2f2d398cfa57fae97bc99826748a602 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Sat, 23 Mar 2013 03:49:53 +0000 +Subject: efivars: pstore: Do not check size when erasing variable + +From: Ben Hutchings + +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 +Cc: Rui Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + 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++) diff --git a/queue-3.4/n_gsm-avoid-accessing-freed-memory-during-cmd_fcoff-condition.patch b/queue-3.4/n_gsm-avoid-accessing-freed-memory-during-cmd_fcoff-condition.patch new file mode 100644 index 00000000000..de8681578bc --- /dev/null +++ b/queue-3.4/n_gsm-avoid-accessing-freed-memory-during-cmd_fcoff-condition.patch @@ -0,0 +1,141 @@ +From 93ed2b137b974b6515f0c847438c7d78a567c1ce Mon Sep 17 00:00:00 2001 +From: Russ Gorby +Date: Mon, 13 Aug 2012 13:44:59 +0100 +Subject: n_gsm: avoid accessing freed memory during CMD_FCOFF condition + +From: Russ Gorby + +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 +Tested-by: Yin, Fengwei +Signed-off-by: Alan Cox +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Ben Hutchings +Cc: Rui Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-3.4/n_gsm-flow-control-handling-in-mux-driver.patch b/queue-3.4/n_gsm-flow-control-handling-in-mux-driver.patch new file mode 100644 index 00000000000..9bfddb26c2c --- /dev/null +++ b/queue-3.4/n_gsm-flow-control-handling-in-mux-driver.patch @@ -0,0 +1,202 @@ +From 6e9b3851b52f170abd7e7cabd01f34f327626c1c Mon Sep 17 00:00:00 2001 +From: Frederic Berat +Date: Mon, 13 Aug 2012 13:43:58 +0100 +Subject: n_gsm : Flow control handling in Mux driver + +From: Frederic Berat + +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 +Signed-off-by: Russ Gorby +Signed-off-by: Alan Cox +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Ben Hutchings +Cc: Rui Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-3.4/n_gsm-replace-kfree_skb-w-appropriate-dev_-versions.patch b/queue-3.4/n_gsm-replace-kfree_skb-w-appropriate-dev_-versions.patch new file mode 100644 index 00000000000..c8374eb8a98 --- /dev/null +++ b/queue-3.4/n_gsm-replace-kfree_skb-w-appropriate-dev_-versions.patch @@ -0,0 +1,65 @@ +From 0afc4d3b3b1320437cdcc8a290ba9dd9dabe35c0 Mon Sep 17 00:00:00 2001 +From: Russ Gorby +Date: Mon, 13 Aug 2012 13:45:15 +0100 +Subject: n_gsm: replace kfree_skb w/ appropriate dev_* versions + +From: Russ Gorby + +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 +Tested-by: Yin, Fengwei +Signed-off-by: Alan Cox +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Ben Hutchings +Cc: Rui Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-3.4/ptrace-x86-introduce-set_task_blockstep-helper.patch b/queue-3.4/ptrace-x86-introduce-set_task_blockstep-helper.patch new file mode 100644 index 00000000000..c6cf9427703 --- /dev/null +++ b/queue-3.4/ptrace-x86-introduce-set_task_blockstep-helper.patch @@ -0,0 +1,89 @@ +From 6d0d3f3aca8f6ec0cd91d062abab0196905a9352 Mon Sep 17 00:00:00 2001 +From: Oleg Nesterov +Date: Fri, 3 Aug 2012 17:31:46 +0200 +Subject: ptrace/x86: Introduce set_task_blockstep() helper + +From: Oleg Nesterov + +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 +Acked-by: Srikar Dronamraju +Signed-off-by: Ben Hutchings +Cc: Rui Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-3.4/ptrace-x86-partly-fix-set_task_blockstep-update_debugctlmsr-logic.patch b/queue-3.4/ptrace-x86-partly-fix-set_task_blockstep-update_debugctlmsr-logic.patch new file mode 100644 index 00000000000..7df1d300c87 --- /dev/null +++ b/queue-3.4/ptrace-x86-partly-fix-set_task_blockstep-update_debugctlmsr-logic.patch @@ -0,0 +1,81 @@ +From 667958738244e5be2cb1e05ab1f2a112c52e1c64 Mon Sep 17 00:00:00 2001 +From: Oleg Nesterov +Date: Sat, 11 Aug 2012 18:06:42 +0200 +Subject: ptrace/x86: Partly fix set_task_blockstep()->update_debugctlmsr() logic + +From: Oleg Nesterov + +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 +Signed-off-by: Ben Hutchings +Cc: Rui Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + 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(); + } + + /* diff --git a/queue-3.4/series b/queue-3.4/series index 602dec3a265..b604498b4c2 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -126,3 +126,21 @@ alsa-hda-add-stereo-dmic-fixup-for-acer-aspire-one-522.patch 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 diff --git a/queue-3.4/tty-serial-imx-don-t-reinit-clock-in-imx_setup_ufcr.patch b/queue-3.4/tty-serial-imx-don-t-reinit-clock-in-imx_setup_ufcr.patch new file mode 100644 index 00000000000..6f6b622f75b --- /dev/null +++ b/queue-3.4/tty-serial-imx-don-t-reinit-clock-in-imx_setup_ufcr.patch @@ -0,0 +1,69 @@ +From da75c41ed3cf1fc577b24dc87559bd32e27ebc8b Mon Sep 17 00:00:00 2001 +From: Dirk Behme +Date: Fri, 31 Aug 2012 10:02:47 +0200 +Subject: tty: serial: imx: don't reinit clock in imx_setup_ufcr() + +From: Dirk Behme + +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 +CC: Shawn Guo +CC: Sascha Hauer +CC: Troy Kisky +CC: Xinyu Chen +Acked-by: Shawn Guo +Signed-off-by: Greg Kroah-Hartman +[bwh: Backported to 3.2: deleted code in imx_setup_ufcr() refers to + sport->clk not sport->clk_per] +Signed-off-by: Ben Hutchings +Cc: Rui Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } + diff --git a/queue-3.4/x86-apic-disable-i-o-apic-before-shutdown-of-the-local-apic.patch b/queue-3.4/x86-apic-disable-i-o-apic-before-shutdown-of-the-local-apic.patch new file mode 100644 index 00000000000..8f172ad4588 --- /dev/null +++ b/queue-3.4/x86-apic-disable-i-o-apic-before-shutdown-of-the-local-apic.patch @@ -0,0 +1,70 @@ +From d8c3245c97490cb68ceaa983b5fce19055b4e331 Mon Sep 17 00:00:00 2001 +From: Fenghua Yu +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 + +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 +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 +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings +Cc: Rui Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + 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 diff --git a/queue-3.4/x86-build-icc-remove-uninitialized_var-from-compiler-intel.h.patch b/queue-3.4/x86-build-icc-remove-uninitialized_var-from-compiler-intel.h.patch new file mode 100644 index 00000000000..3df561fc952 --- /dev/null +++ b/queue-3.4/x86-build-icc-remove-uninitialized_var-from-compiler-intel.h.patch @@ -0,0 +1,36 @@ +From 4fe644c42cb5980bfa920fdf9f1d1bc306328c52 Mon Sep 17 00:00:00 2001 +From: "H. Peter Anvin" +Date: Tue, 10 Dec 2013 14:56:06 -0800 +Subject: x86, build, icc: Remove uninitialized_var() from compiler-intel.h + +From: "H. Peter Anvin" + +commit 503cf95c061a0551eb684da364509297efbe55d9 upstream. + +When compiling with icc, 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 +Cc: Kevin B. Smith +Signed-off-by: H. Peter Anvin +Link: http://lkml.kernel.org/n/tip-0mbwou1zt7pafij09b897lg3@git.kernel.org +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings +Cc: Rui Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + 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 diff --git a/queue-3.4/x86-build-pass-in-additional-mno-mmx-mno-sse-options.patch b/queue-3.4/x86-build-pass-in-additional-mno-mmx-mno-sse-options.patch new file mode 100644 index 00000000000..de165dbb8ed --- /dev/null +++ b/queue-3.4/x86-build-pass-in-additional-mno-mmx-mno-sse-options.patch @@ -0,0 +1,77 @@ +From 612e9718fa791e611c17e1949841766b122a817b Mon Sep 17 00:00:00 2001 +From: "H. Peter Anvin" +Date: Mon, 9 Dec 2013 15:43:38 -0800 +Subject: x86, build: Pass in additional -mno-mmx, -mno-sse options + +From: "H. Peter Anvin" + +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 +Cc: Sunil K. Pandey +Signed-off-by: H. Peter Anvin +Cc: H. J. Lu +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 +Cc: Rui Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + 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) + diff --git a/queue-3.4/x86-fix-build-error-and-kconfig-for-ia32_emulation-and-binfmt.patch b/queue-3.4/x86-fix-build-error-and-kconfig-for-ia32_emulation-and-binfmt.patch new file mode 100644 index 00000000000..7f0c7aac62b --- /dev/null +++ b/queue-3.4/x86-fix-build-error-and-kconfig-for-ia32_emulation-and-binfmt.patch @@ -0,0 +1,43 @@ +From ea3d15ac86cb9697fdabdc801553171b83b35372 Mon Sep 17 00:00:00 2001 +From: Randy Dunlap +Date: Tue, 18 Jun 2013 12:33:40 -0700 +Subject: x86: fix build error and kconfig for ia32_emulation and binfmt + +From: Randy Dunlap + +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 +Link: http://lkml.kernel.org/r/51C0B614.5000708@infradead.org +Signed-off-by: H. Peter Anvin +Signed-off-by: Ben Hutchings +Cc: Rui Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + 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 diff --git a/queue-3.4/x86-get_unmapped_area-access-mmap_legacy_base-through-mm_struct-member.patch b/queue-3.4/x86-get_unmapped_area-access-mmap_legacy_base-through-mm_struct-member.patch new file mode 100644 index 00000000000..f9e895e08f7 --- /dev/null +++ b/queue-3.4/x86-get_unmapped_area-access-mmap_legacy_base-through-mm_struct-member.patch @@ -0,0 +1,75 @@ +From ac8905cf6be324c76193debc26042fe7a746f89a Mon Sep 17 00:00:00 2001 +From: Radu Caragea +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 + +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 +Reported-and-tested-by: Jeff Shorey +Cc: Andrew Morton +Cc: Michel Lespinasse +Cc: Oleg Nesterov +Cc: Rik van Riel +Cc: Ingo Molnar +Cc: Adrian Sendroiu +Cc: Greg KH +Cc: Kamal Mostafa +Signed-off-by: Linus Torvalds +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings +Cc: Rui Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + 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 */ diff --git a/queue-3.4/x86-sandy-bridge-mark-arrays-in-__init-functions-as-__initconst.patch b/queue-3.4/x86-sandy-bridge-mark-arrays-in-__init-functions-as-__initconst.patch new file mode 100644 index 00000000000..21e11b8375e --- /dev/null +++ b/queue-3.4/x86-sandy-bridge-mark-arrays-in-__init-functions-as-__initconst.patch @@ -0,0 +1,45 @@ +From 91c90db1aa92a50fa1d7f289502b49ddb46a90d3 Mon Sep 17 00:00:00 2001 +From: "H. Peter Anvin" +Date: Sun, 13 Jan 2013 20:36:39 -0800 +Subject: x86/Sandy Bridge: mark arrays in __init functions as __initconst + +From: "H. Peter Anvin" + +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 +Link: http://lkml.kernel.org/r/75F4BEE6-CB0E-4426-B40B-697451677738@googlemail.com +Signed-off-by: H. Peter Anvin +Signed-off-by: Ben Hutchings +Cc: Rui Xiang +Signed-off-by: Greg Kroah-Hartman + +--- + 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,