From: Ben Hutchings <ben@decadent.org.uk>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: akpm@linux-foundation.org, Josh Boyer <jwboyer@redhat.com>,
Seiji Aguchi <seiji.aguchi@hds.com>,
Mike Waychison <mikew@google.com>,
Matt Fleming <matt.fleming@intel.com>,
Tony Luck <tony.luck@intel.com>
Subject: [ 39/82] efivars: Disable external interrupt while holding efivars->lock
Date: Mon, 18 Mar 2013 04:22:23 +0000 [thread overview]
Message-ID: <20130318042148.005388539@decadent.org.uk> (raw)
In-Reply-To: <20130318042144.234468645@decadent.org.uk>
3.2-stable review patch. If anyone has any objections, please let me know.
------------------
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>
---
drivers/firmware/efivars.c | 84 ++++++++++++++++++++++++----------------------
1 file changed, 43 insertions(+), 41 deletions(-)
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -393,10 +393,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",
@@ -525,14 +526,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",
@@ -643,7 +644,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;
@@ -653,7 +654,7 @@ static int efi_pstore_close(struct pstor
{
struct efivars *efivars = psi->data;
- spin_unlock(&efivars->lock);
+ spin_unlock_irq(&efivars->lock);
return 0;
}
@@ -708,11 +709,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.
@@ -724,7 +726,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;
}
@@ -765,7 +767,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);
@@ -848,7 +850,7 @@ static ssize_t efivar_create(struct file
return -EINVAL;
}
- spin_lock(&efivars->lock);
+ spin_lock_irq(&efivars->lock);
/*
* Does this variable already exist?
@@ -866,7 +868,7 @@ static ssize_t efivar_create(struct file
}
}
if (found) {
- spin_unlock(&efivars->lock);
+ spin_unlock_irq(&efivars->lock);
return -EINVAL;
}
@@ -880,10 +882,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,
@@ -911,7 +913,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?
@@ -929,7 +931,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 */
@@ -945,12 +947,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.... */
@@ -1058,9 +1060,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;
}
@@ -1129,9 +1131,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)
next prev parent reply other threads:[~2013-03-18 4:22 UTC|newest]
Thread overview: 87+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-18 4:21 [ 00/82] 3.2.41-stable review Ben Hutchings
2013-03-18 4:21 ` [ 01/82] Revert "powerpc/eeh: Fix crash when adding a device in a slot with DDW" Ben Hutchings
2013-03-18 4:21 ` [ 02/82] btrfs: Init io_lock after cloning btrfs device struct Ben Hutchings
2013-03-18 4:21 ` [ 03/82] md: protect against crash upon fsync on ro array Ben Hutchings
2013-03-18 4:21 ` [ 04/82] NFS: Dont allow NFS silly-renamed files to be deleted, no signal Ben Hutchings
2013-03-18 4:21 ` [ 05/82] SUNRPC: Dont start the retransmission timer when out of socket space Ben Hutchings
2013-03-18 4:21 ` [ 06/82] [SCSI] storvsc: Initialize the sglist Ben Hutchings
2013-03-18 4:21 ` [ 07/82] [SCSI] dc395x: uninitialized variable in device_alloc() Ben Hutchings
2013-03-18 4:21 ` [ 08/82] ARM: VFP: fix emulation of second VFP instruction Ben Hutchings
2013-03-18 4:21 ` [ 09/82] ARM: fix scheduling while atomic warning in alignment handling code Ben Hutchings
2013-03-18 4:21 ` [ 10/82] md: fix two bugs when attempting to resize RAID0 array Ben Hutchings
2013-03-18 4:21 ` [ 11/82] md: raid0: fix error return from create_stripe_zones Ben Hutchings
2013-03-18 4:21 ` [ 12/82] proc connector: reject unprivileged listener bumps Ben Hutchings
2013-03-18 4:21 ` [ 13/82] ath9k: fix RSSI dummy marker value Ben Hutchings
2013-03-18 4:21 ` [ 14/82] ath9k_htc: fix signal strength handling issues Ben Hutchings
2013-03-18 4:21 ` [ 15/82] mwifiex: correct sleep delay counter Ben Hutchings
2013-03-18 4:22 ` [ 16/82] cifs: ensure that cifs_get_root() only traverses directories Ben Hutchings
2013-03-18 4:22 ` [ 17/82] xen/pci: We dont do multiple MSIs Ben Hutchings
2013-03-18 4:22 ` [ 18/82] dm: fix truncated status strings Ben Hutchings
2013-03-18 4:22 ` [ 19/82] dm snapshot: add missing module aliases Ben Hutchings
2013-03-18 4:22 ` [ 20/82] drm/i915: Dont clobber crtc->fb when queue_flip fails Ben Hutchings
2013-03-18 4:22 ` [ 21/82] ARM: 7663/1: perf: fix ARMv7 EVTYPE_MASK to include NSH bit Ben Hutchings
2013-03-18 4:22 ` [ 22/82] hwmon: (pmbus/ltc2978) Fix peak attribute handling Ben Hutchings
2013-03-18 4:22 ` [ 23/82] hwmon: (pmbus/ltc2978) Use detected chip ID to select supported functionality Ben Hutchings
2013-03-18 4:22 ` [ 24/82] hwmon: (sht15) Check return value of regulator_enable() Ben Hutchings
2013-03-18 4:22 ` [ 25/82] hw_random: make buffer usable in scatterlist Ben Hutchings
2013-03-18 4:22 ` [ 26/82] ALSA: vmaster: Fix slave change notification Ben Hutchings
2013-03-18 4:22 ` [ 27/82] drm/radeon: add primary dac adj quirk for R200 board Ben Hutchings
2013-03-18 4:22 ` [ 28/82] dmi_scan: fix missing check for _DMI_ signature in smbios_present() Ben Hutchings
2013-03-18 4:22 ` [ 29/82] iwlwifi: always copy first 16 bytes of commands Ben Hutchings
2013-03-18 4:22 ` [ 30/82] HID: add support for Sony RF receiver with USB product id 0x0374 Ben Hutchings
2013-03-18 4:22 ` [ 31/82] HID: clean up quirk for Sony RF receivers Ben Hutchings
2013-03-18 4:22 ` [ 32/82] ahci: AHCI-mode SATA patch for Intel Lynx Point DeviceIDs Ben Hutchings
2013-03-18 4:22 ` [ 33/82] ahci: Add Device IDs for Intel Lynx Point-LP PCH Ben Hutchings
2013-03-18 4:22 ` [ 34/82] ahci: AHCI-mode SATA patch for Intel Avoton DeviceIDs Ben Hutchings
2013-03-18 4:22 ` [ 35/82] ahci: Add Device IDs for Intel Wellsburg PCH Ben Hutchings
2013-03-18 4:22 ` [ 36/82] iommu/amd: Initialize device table after dma_ops Ben Hutchings
2013-03-18 4:22 ` [ 37/82] tty: Correct tty buffer flush Ben Hutchings
2013-03-18 4:22 ` [ 38/82] efi_pstore: Check remaining space with QueryVariableInfo() before writing data Ben Hutchings
2013-03-18 4:22 ` Ben Hutchings [this message]
2013-03-18 4:22 ` [ 40/82] efi: be more paranoid about available space when creating variables Ben Hutchings
2013-03-18 4:22 ` [ 41/82] ftrace: Update the kconfig for DYNAMIC_FTRACE Ben Hutchings
2013-03-18 4:22 ` [ 42/82] decnet: Fix disappearing sysctl entries Ben Hutchings
2013-03-18 4:22 ` [ 43/82] Fix memory leak in cpufreq stats Ben Hutchings
2013-03-18 4:22 ` [ 44/82] vfs: fix pipe counter breakage Ben Hutchings
2013-03-18 4:22 ` [ 45/82] USB: EHCI: dont check DMA values in QH overlays Ben Hutchings
2013-03-19 3:09 ` Ben Hutchings
2013-03-19 15:27 ` Alan Stern
2013-03-19 20:31 ` Ben Hutchings
2013-03-18 4:22 ` [ 46/82] xen/pciback: Dont disable a PCI device that is already disabled Ben Hutchings
2013-03-18 4:22 ` [ 47/82] USB: option: add Huawei E5331 Ben Hutchings
2013-03-18 4:22 ` [ 48/82] USB: storage: fix Huawei mode switching regression Ben Hutchings
2013-03-18 4:22 ` [ 49/82] USB: added support for Cinterions products AH6 and PLS8 Ben Hutchings
2013-03-18 4:22 ` [ 50/82] e1000e: fix pci-device enable-counter balance Ben Hutchings
2013-03-18 4:22 ` [ 51/82] virtio: rng: disallow multiple device registrations, fixes crashes Ben Hutchings
2013-03-18 4:22 ` [ 52/82] ALSA: seq: Fix missing error handling in snd_seq_timer_open() Ben Hutchings
2013-03-18 4:22 ` [ 53/82] usb: cp210x new Vendor/Device IDs Ben Hutchings
2013-03-18 4:22 ` [ 54/82] staging: vt6656: Fix oops on resume from suspend Ben Hutchings
2013-03-18 4:22 ` [ 55/82] qcaux: add Franklin U600 Ben Hutchings
2013-03-18 4:22 ` [ 56/82] ext3: Fix format string issues Ben Hutchings
2013-03-18 4:22 ` [ 57/82] keys: fix race with concurrent install_user_keyrings() Ben Hutchings
2013-03-18 4:22 ` [ 58/82] tty/serial: Add support for Altera serial port Ben Hutchings
2013-03-18 4:22 ` [ 59/82] Fix 4 port and add support for 8 port Unknown PCI serial port cards Ben Hutchings
2013-03-18 4:22 ` [ 60/82] serial: 8250_pci: add support for another kind of NetMos Technology PCI 9835 Multi-I/O Controller Ben Hutchings
2013-03-18 4:22 ` [ 61/82] tty: serial: fix typo "ARCH_S5P6450" Ben Hutchings
2013-03-18 4:22 ` [ 62/82] usb: serial: Add Rigblaster Advantage to device table Ben Hutchings
2013-03-18 4:22 ` [ 63/82] w1: fix oops when w1_search is called from netlink connector Ben Hutchings
2013-03-18 4:22 ` [ 64/82] USB: cdc-wdm: fix buffer overflow Ben Hutchings
2013-03-18 4:22 ` [ 65/82] signal: always clear sa_restorer on execve Ben Hutchings
2013-03-18 4:22 ` [ 66/82] hwmon: (lineage-pem) Add missing terminating entry for pem_[input|fan]_attributes Ben Hutchings
2013-03-18 4:22 ` [ 67/82] hwmon: (pmbus/ltc2978) Fix temperature reporting Ben Hutchings
2013-03-18 4:22 ` [ 68/82] crypto: user - fix info leaks in report API Ben Hutchings
2013-03-18 4:22 ` [ 69/82] Fix: compat_rw_copy_check_uvector() misuse in aio, readv, writev, and security keys Ben Hutchings
2013-03-18 4:22 ` [ 70/82] USB: Dont use EHCI port sempahore for USB 3.0 hubs Ben Hutchings
2013-03-18 4:22 ` [ 71/82] USB: Prepare for refactoring by adding extra udev checks Ben Hutchings
2013-03-18 4:22 ` [ 72/82] USB: Rip out recursive call on warm port reset Ben Hutchings
2013-03-18 4:22 ` [ 73/82] USB: Fix connected device switch to Inactive state Ben Hutchings
2013-03-18 4:22 ` [ 74/82] batman-adv: bat_socket_read missing checks Ben Hutchings
2013-03-18 4:22 ` [ 75/82] batman-adv: Only write requested number of byte to user buffer Ben Hutchings
2013-03-18 4:23 ` [ 76/82] mm/hotplug: correctly add new zone to all other nodes zone lists Ben Hutchings
2013-03-18 4:23 ` [ 77/82] xen-netfront: delay gARP until backend switches to Connected Ben Hutchings
2013-03-18 4:23 ` [ 78/82] block: use i_size_write() in bd_set_size() Ben Hutchings
2013-03-18 4:23 ` [ 79/82] loopdev: fix a deadlock Ben Hutchings
2013-03-18 4:23 ` [ 80/82] loopdev: remove an user triggerable oops Ben Hutchings
2013-03-18 4:23 ` [ 81/82] btrfs: use rcu_barrier() to wait for bdev puts at unmount Ben Hutchings
2013-03-18 4:23 ` [ 82/82] NLS: improve UTF8 -> UTF16 string conversion routine Ben Hutchings
2013-03-18 5:00 ` [ 00/82] 3.2.41-stable review Ben Hutchings
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130318042148.005388539@decadent.org.uk \
--to=ben@decadent.org.uk \
--cc=akpm@linux-foundation.org \
--cc=jwboyer@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=matt.fleming@intel.com \
--cc=mikew@google.com \
--cc=seiji.aguchi@hds.com \
--cc=stable@vger.kernel.org \
--cc=tony.luck@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).