linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg KH <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: torvalds@linux-foundation.org, akpm@linux-foundation.org,
	alan@lxorguk.ukuu.org.uk, Andrew Barry <abarry@cray.com>,
	David Gibson <david@gibson.dropbear.id.au>,
	Hugh Dickins <hughd@google.com>, Mel Gorman <mgorman@suse.de>,
	Minchan Kim <minchan.kim@gmail.com>,
	Hillf Danton <dhillf@gmail.com>,
	Paul Mackerras <paulus@samba.org>
Subject: [ 46/52] hugepages: fix use after free bug in "quota" handling
Date: Thu, 10 May 2012 10:32:18 -0700	[thread overview]
Message-ID: <20120510173136.896369991@linuxfoundation.org> (raw)
In-Reply-To: <20120510173229.GA5678@kroah.com>

3.3-stable review patch.  If anyone has any objections, please let me know.

------------------

From: David Gibson <david@gibson.dropbear.id.au>

commit 90481622d75715bfcb68501280a917dbfe516029 upstream.

hugetlbfs_{get,put}_quota() are badly named.  They don't interact with the
general quota handling code, and they don't much resemble its behaviour.
Rather than being about maintaining limits on on-disk block usage by
particular users, they are instead about maintaining limits on in-memory
page usage (including anonymous MAP_PRIVATE copied-on-write pages)
associated with a particular hugetlbfs filesystem instance.

Worse, they work by having callbacks to the hugetlbfs filesystem code from
the low-level page handling code, in particular from free_huge_page().
This is a layering violation of itself, but more importantly, if the
kernel does a get_user_pages() on hugepages (which can happen from KVM
amongst others), then the free_huge_page() can be delayed until after the
associated inode has already been freed.  If an unmount occurs at the
wrong time, even the hugetlbfs superblock where the "quota" limits are
stored may have been freed.

Andrew Barry proposed a patch to fix this by having hugepages, instead of
storing a pointer to their address_space and reaching the superblock from
there, had the hugepages store pointers directly to the superblock,
bumping the reference count as appropriate to avoid it being freed.
Andrew Morton rejected that version, however, on the grounds that it made
the existing layering violation worse.

This is a reworked version of Andrew's patch, which removes the extra, and
some of the existing, layering violation.  It works by introducing the
concept of a hugepage "subpool" at the lower hugepage mm layer - that is a
finite logical pool of hugepages to allocate from.  hugetlbfs now creates
a subpool for each filesystem instance with a page limit set, and a
pointer to the subpool gets added to each allocated hugepage, instead of
the address_space pointer used now.  The subpool has its own lifetime and
is only freed once all pages in it _and_ all other references to it (i.e.
superblocks) are gone.

subpools are optional - a NULL subpool pointer is taken by the code to
mean that no subpool limits are in effect.

Previous discussion of this bug found in:  "Fix refcounting in hugetlbfs
quota handling.". See:  https://lkml.org/lkml/2011/8/11/28 or
http://marc.info/?l=linux-mm&m=126928970510627&w=1

v2: Fixed a bug spotted by Hillf Danton, and removed the extra parameter to
alloc_huge_page() - since it already takes the vma, it is not necessary.

Signed-off-by: Andrew Barry <abarry@cray.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Cc: Hugh Dickins <hughd@google.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Minchan Kim <minchan.kim@gmail.com>
Cc: Hillf Danton <dhillf@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 fs/hugetlbfs/inode.c    |   54 +++++++------------
 include/linux/hugetlb.h |   14 +++-
 mm/hugetlb.c            |  135 ++++++++++++++++++++++++++++++++++++++----------
 3 files changed, 139 insertions(+), 64 deletions(-)

--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -600,9 +600,15 @@ static int hugetlbfs_statfs(struct dentr
 		spin_lock(&sbinfo->stat_lock);
 		/* If no limits set, just report 0 for max/free/used
 		 * blocks, like simple_statfs() */
-		if (sbinfo->max_blocks >= 0) {
-			buf->f_blocks = sbinfo->max_blocks;
-			buf->f_bavail = buf->f_bfree = sbinfo->free_blocks;
+		if (sbinfo->spool) {
+			long free_pages;
+
+			spin_lock(&sbinfo->spool->lock);
+			buf->f_blocks = sbinfo->spool->max_hpages;
+			free_pages = sbinfo->spool->max_hpages
+				- sbinfo->spool->used_hpages;
+			buf->f_bavail = buf->f_bfree = free_pages;
+			spin_unlock(&sbinfo->spool->lock);
 			buf->f_files = sbinfo->max_inodes;
 			buf->f_ffree = sbinfo->free_inodes;
 		}
@@ -618,6 +624,10 @@ static void hugetlbfs_put_super(struct s
 
 	if (sbi) {
 		sb->s_fs_info = NULL;
+
+		if (sbi->spool)
+			hugepage_put_subpool(sbi->spool);
+
 		kfree(sbi);
 	}
 }
@@ -848,10 +858,14 @@ hugetlbfs_fill_super(struct super_block
 	sb->s_fs_info = sbinfo;
 	sbinfo->hstate = config.hstate;
 	spin_lock_init(&sbinfo->stat_lock);
-	sbinfo->max_blocks = config.nr_blocks;
-	sbinfo->free_blocks = config.nr_blocks;
 	sbinfo->max_inodes = config.nr_inodes;
 	sbinfo->free_inodes = config.nr_inodes;
+	sbinfo->spool = NULL;
+	if (config.nr_blocks != -1) {
+		sbinfo->spool = hugepage_new_subpool(config.nr_blocks);
+		if (!sbinfo->spool)
+			goto out_free;
+	}
 	sb->s_maxbytes = MAX_LFS_FILESIZE;
 	sb->s_blocksize = huge_page_size(config.hstate);
 	sb->s_blocksize_bits = huge_page_shift(config.hstate);
@@ -870,38 +884,12 @@ hugetlbfs_fill_super(struct super_block
 	sb->s_root = root;
 	return 0;
 out_free:
+	if (sbinfo->spool)
+		kfree(sbinfo->spool);
 	kfree(sbinfo);
 	return -ENOMEM;
 }
 
-int hugetlb_get_quota(struct address_space *mapping, long delta)
-{
-	int ret = 0;
-	struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb);
-
-	if (sbinfo->free_blocks > -1) {
-		spin_lock(&sbinfo->stat_lock);
-		if (sbinfo->free_blocks - delta >= 0)
-			sbinfo->free_blocks -= delta;
-		else
-			ret = -ENOMEM;
-		spin_unlock(&sbinfo->stat_lock);
-	}
-
-	return ret;
-}
-
-void hugetlb_put_quota(struct address_space *mapping, long delta)
-{
-	struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(mapping->host->i_sb);
-
-	if (sbinfo->free_blocks > -1) {
-		spin_lock(&sbinfo->stat_lock);
-		sbinfo->free_blocks += delta;
-		spin_unlock(&sbinfo->stat_lock);
-	}
-}
-
 static struct dentry *hugetlbfs_mount(struct file_system_type *fs_type,
 	int flags, const char *dev_name, void *data)
 {
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -14,6 +14,15 @@ struct user_struct;
 #include <linux/shm.h>
 #include <asm/tlbflush.h>
 
+struct hugepage_subpool {
+	spinlock_t lock;
+	long count;
+	long max_hpages, used_hpages;
+};
+
+struct hugepage_subpool *hugepage_new_subpool(long nr_blocks);
+void hugepage_put_subpool(struct hugepage_subpool *spool);
+
 int PageHuge(struct page *page);
 
 void reset_vma_resv_huge_pages(struct vm_area_struct *vma);
@@ -138,12 +147,11 @@ struct hugetlbfs_config {
 };
 
 struct hugetlbfs_sb_info {
-	long	max_blocks;   /* blocks allowed */
-	long	free_blocks;  /* blocks free */
 	long	max_inodes;   /* inodes allowed */
 	long	free_inodes;  /* inodes free */
 	spinlock_t	stat_lock;
 	struct hstate *hstate;
+	struct hugepage_subpool *spool;
 };
 
 
@@ -166,8 +174,6 @@ extern const struct file_operations huge
 extern const struct vm_operations_struct hugetlb_vm_ops;
 struct file *hugetlb_file_setup(const char *name, size_t size, vm_flags_t acct,
 				struct user_struct **user, int creat_flags);
-int hugetlb_get_quota(struct address_space *mapping, long delta);
-void hugetlb_put_quota(struct address_space *mapping, long delta);
 
 static inline int is_file_hugepages(struct file *file)
 {
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -53,6 +53,84 @@ static unsigned long __initdata default_
  */
 static DEFINE_SPINLOCK(hugetlb_lock);
 
+static inline void unlock_or_release_subpool(struct hugepage_subpool *spool)
+{
+	bool free = (spool->count == 0) && (spool->used_hpages == 0);
+
+	spin_unlock(&spool->lock);
+
+	/* If no pages are used, and no other handles to the subpool
+	 * remain, free the subpool the subpool remain */
+	if (free)
+		kfree(spool);
+}
+
+struct hugepage_subpool *hugepage_new_subpool(long nr_blocks)
+{
+	struct hugepage_subpool *spool;
+
+	spool = kmalloc(sizeof(*spool), GFP_KERNEL);
+	if (!spool)
+		return NULL;
+
+	spin_lock_init(&spool->lock);
+	spool->count = 1;
+	spool->max_hpages = nr_blocks;
+	spool->used_hpages = 0;
+
+	return spool;
+}
+
+void hugepage_put_subpool(struct hugepage_subpool *spool)
+{
+	spin_lock(&spool->lock);
+	BUG_ON(!spool->count);
+	spool->count--;
+	unlock_or_release_subpool(spool);
+}
+
+static int hugepage_subpool_get_pages(struct hugepage_subpool *spool,
+				      long delta)
+{
+	int ret = 0;
+
+	if (!spool)
+		return 0;
+
+	spin_lock(&spool->lock);
+	if ((spool->used_hpages + delta) <= spool->max_hpages) {
+		spool->used_hpages += delta;
+	} else {
+		ret = -ENOMEM;
+	}
+	spin_unlock(&spool->lock);
+
+	return ret;
+}
+
+static void hugepage_subpool_put_pages(struct hugepage_subpool *spool,
+				       long delta)
+{
+	if (!spool)
+		return;
+
+	spin_lock(&spool->lock);
+	spool->used_hpages -= delta;
+	/* If hugetlbfs_put_super couldn't free spool due to
+	* an outstanding quota reference, free it now. */
+	unlock_or_release_subpool(spool);
+}
+
+static inline struct hugepage_subpool *subpool_inode(struct inode *inode)
+{
+	return HUGETLBFS_SB(inode->i_sb)->spool;
+}
+
+static inline struct hugepage_subpool *subpool_vma(struct vm_area_struct *vma)
+{
+	return subpool_inode(vma->vm_file->f_dentry->d_inode);
+}
+
 /*
  * Region tracking -- allows tracking of reservations and instantiated pages
  *                    across the pages in a mapping.
@@ -533,9 +611,9 @@ static void free_huge_page(struct page *
 	 */
 	struct hstate *h = page_hstate(page);
 	int nid = page_to_nid(page);
-	struct address_space *mapping;
+	struct hugepage_subpool *spool =
+		(struct hugepage_subpool *)page_private(page);
 
-	mapping = (struct address_space *) page_private(page);
 	set_page_private(page, 0);
 	page->mapping = NULL;
 	BUG_ON(page_count(page));
@@ -551,8 +629,7 @@ static void free_huge_page(struct page *
 		enqueue_huge_page(h, page);
 	}
 	spin_unlock(&hugetlb_lock);
-	if (mapping)
-		hugetlb_put_quota(mapping, 1);
+	hugepage_subpool_put_pages(spool, 1);
 }
 
 static void prep_new_huge_page(struct hstate *h, struct page *page, int nid)
@@ -966,11 +1043,12 @@ static void return_unused_surplus_pages(
 /*
  * Determine if the huge page at addr within the vma has an associated
  * reservation.  Where it does not we will need to logically increase
- * reservation and actually increase quota before an allocation can occur.
- * Where any new reservation would be required the reservation change is
- * prepared, but not committed.  Once the page has been quota'd allocated
- * an instantiated the change should be committed via vma_commit_reservation.
- * No action is required on failure.
+ * reservation and actually increase subpool usage before an allocation
+ * can occur.  Where any new reservation would be required the
+ * reservation change is prepared, but not committed.  Once the page
+ * has been allocated from the subpool and instantiated the change should
+ * be committed via vma_commit_reservation.  No action is required on
+ * failure.
  */
 static long vma_needs_reservation(struct hstate *h,
 			struct vm_area_struct *vma, unsigned long addr)
@@ -1019,24 +1097,24 @@ static void vma_commit_reservation(struc
 static struct page *alloc_huge_page(struct vm_area_struct *vma,
 				    unsigned long addr, int avoid_reserve)
 {
+	struct hugepage_subpool *spool = subpool_vma(vma);
 	struct hstate *h = hstate_vma(vma);
 	struct page *page;
-	struct address_space *mapping = vma->vm_file->f_mapping;
-	struct inode *inode = mapping->host;
 	long chg;
 
 	/*
-	 * Processes that did not create the mapping will have no reserves and
-	 * will not have accounted against quota. Check that the quota can be
-	 * made before satisfying the allocation
-	 * MAP_NORESERVE mappings may also need pages and quota allocated
-	 * if no reserve mapping overlaps.
+	 * Processes that did not create the mapping will have no
+	 * reserves and will not have accounted against subpool
+	 * limit. Check that the subpool limit can be made before
+	 * satisfying the allocation MAP_NORESERVE mappings may also
+	 * need pages and subpool limit allocated allocated if no reserve
+	 * mapping overlaps.
 	 */
 	chg = vma_needs_reservation(h, vma, addr);
 	if (chg < 0)
 		return ERR_PTR(-VM_FAULT_OOM);
 	if (chg)
-		if (hugetlb_get_quota(inode->i_mapping, chg))
+		if (hugepage_subpool_get_pages(spool, chg))
 			return ERR_PTR(-VM_FAULT_SIGBUS);
 
 	spin_lock(&hugetlb_lock);
@@ -1046,12 +1124,12 @@ static struct page *alloc_huge_page(stru
 	if (!page) {
 		page = alloc_buddy_huge_page(h, NUMA_NO_NODE);
 		if (!page) {
-			hugetlb_put_quota(inode->i_mapping, chg);
+			hugepage_subpool_put_pages(spool, chg);
 			return ERR_PTR(-VM_FAULT_SIGBUS);
 		}
 	}
 
-	set_page_private(page, (unsigned long) mapping);
+	set_page_private(page, (unsigned long)spool);
 
 	vma_commit_reservation(h, vma, addr);
 
@@ -2072,6 +2150,7 @@ static void hugetlb_vm_op_close(struct v
 {
 	struct hstate *h = hstate_vma(vma);
 	struct resv_map *reservations = vma_resv_map(vma);
+	struct hugepage_subpool *spool = subpool_vma(vma);
 	unsigned long reserve;
 	unsigned long start;
 	unsigned long end;
@@ -2087,7 +2166,7 @@ static void hugetlb_vm_op_close(struct v
 
 		if (reserve) {
 			hugetlb_acct_memory(h, -reserve);
-			hugetlb_put_quota(vma->vm_file->f_mapping, reserve);
+			hugepage_subpool_put_pages(spool, reserve);
 		}
 	}
 }
@@ -2316,7 +2395,7 @@ static int unmap_ref_private(struct mm_s
 	 */
 	address = address & huge_page_mask(h);
 	pgoff = vma_hugecache_offset(h, vma, address);
-	mapping = (struct address_space *)page_private(page);
+	mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
 
 	/*
 	 * Take the mapping lock for the duration of the table walk. As
@@ -2871,11 +2950,12 @@ int hugetlb_reserve_pages(struct inode *
 {
 	long ret, chg;
 	struct hstate *h = hstate_inode(inode);
+	struct hugepage_subpool *spool = subpool_inode(inode);
 
 	/*
 	 * Only apply hugepage reservation if asked. At fault time, an
 	 * attempt will be made for VM_NORESERVE to allocate a page
-	 * and filesystem quota without using reserves
+	 * without using reserves
 	 */
 	if (vm_flags & VM_NORESERVE)
 		return 0;
@@ -2902,17 +2982,17 @@ int hugetlb_reserve_pages(struct inode *
 	if (chg < 0)
 		return chg;
 
-	/* There must be enough filesystem quota for the mapping */
-	if (hugetlb_get_quota(inode->i_mapping, chg))
+	/* There must be enough pages in the subpool for the mapping */
+	if (hugepage_subpool_get_pages(spool, chg))
 		return -ENOSPC;
 
 	/*
 	 * Check enough hugepages are available for the reservation.
-	 * Hand back the quota if there are not
+	 * Hand the pages back to the subpool if there are not
 	 */
 	ret = hugetlb_acct_memory(h, chg);
 	if (ret < 0) {
-		hugetlb_put_quota(inode->i_mapping, chg);
+		hugepage_subpool_put_pages(spool, chg);
 		return ret;
 	}
 
@@ -2936,12 +3016,13 @@ void hugetlb_unreserve_pages(struct inod
 {
 	struct hstate *h = hstate_inode(inode);
 	long chg = region_truncate(&inode->i_mapping->private_list, offset);
+	struct hugepage_subpool *spool = subpool_inode(inode);
 
 	spin_lock(&inode->i_lock);
 	inode->i_blocks -= (blocks_per_huge_page(h) * freed);
 	spin_unlock(&inode->i_lock);
 
-	hugetlb_put_quota(inode->i_mapping, (chg - freed));
+	hugepage_subpool_put_pages(spool, (chg - freed));
 	hugetlb_acct_memory(h, -(chg - freed));
 }
 



  parent reply	other threads:[~2012-05-10 17:36 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-05-10 17:32 [ 00/52] 3.3.6-stable review Greg KH
2012-05-10 17:31 ` [ 01/52] drm/i915: enable dip before writing data on gen4 Greg KH
2012-05-10 17:31 ` [ 02/52] smsc95xx: mark link down on startup and let PHY interrupt deal with carrier changes Greg KH
2012-05-10 17:31 ` [ 03/52] e1000: fix vlan processing regression Greg KH
2012-05-10 17:31 ` [ 04/52] xen/pte: Fix crashes when trying to see non-existent PGD/PMD/PUD/PTEs Greg KH
2012-05-10 17:31 ` [ 05/52] xen/pci: dont use PCI BIOS service for configuration space accesses Greg KH
2012-05-10 17:31 ` [ 06/52] drm/i915: disable sdvo hotplug on i945g/gm Greg KH
2012-05-10 17:31 ` [ 07/52] drm/i915: Do no set Stencil Cache eviction LRA w/a on gen7+ Greg KH
2012-05-10 17:31 ` [ 08/52] ASoC: core: check of_property_count_strings failure Greg KH
2012-05-10 17:31 ` [ 09/52] ASoC: tlv312aic23: unbreak resume Greg KH
2012-05-10 17:31 ` [ 10/52] fs/cifs: fix parsing of dfs referrals Greg KH
2012-05-10 17:31 ` [ 11/52] x86, relocs: Remove an unused variable Greg KH
2012-05-10 17:31 ` [ 12/52] percpu, x86: dont use PMD_SIZE as embedded atom_size on 32bit Greg KH
2012-05-10 17:31 ` [ 13/52] asm-generic: Use __BITS_PER_LONG in statfs.h Greg KH
2012-05-10 17:31 ` [ 14/52] Fix __read_seqcount_begin() to use ACCESS_ONCE for sequence value read Greg KH
2012-05-10 17:31 ` [ 15/52] ARM: 7410/1: Add extra clobber registers for assembly in kernel_execve Greg KH
2012-05-10 17:31 ` [ 16/52] ARM: 7411/1: audit: fix treatment of saved ip register during syscall tracing Greg KH
2012-05-10 17:31 ` [ 17/52] ARM: 7412/1: audit: use only AUDIT_ARCH_ARM regardless of endianness Greg KH
2012-05-10 17:31 ` [ 18/52] ARM: 7414/1: SMP: prevent use of the console when using idmap_pgd Greg KH
2012-05-10 17:31 ` [ 19/52] regulator: Fix the logic to ensure new voltage setting in valid range Greg KH
2012-05-10 17:31 ` [ 20/52] ARM: orion5x: Fix GPIO enable bits for MPP9 Greg KH
2012-05-10 17:31 ` [ 21/52] ARM: OMAP: Revert "ARM: OMAP: ctrl: Fix CONTROL_DSIPHY register fields" Greg KH
2012-05-10 17:31 ` [ 22/52] asix: Fix tx transfer padding for full-speed USB Greg KH
2012-05-10 18:25   ` Mark Lord
2012-05-10 18:29     ` Mark Lord
2012-05-10 18:52       ` David Miller
2012-05-10 17:31 ` [ 23/52] netem: fix possible skb leak Greg KH
2012-05-10 17:31 ` [ 24/52] net: In unregister_netdevice_notifier unregister the netdevices Greg KH
2012-05-10 17:31 ` [ 25/52] net: l2tp: unlock socket lock before returning from l2tp_ip_sendmsg Greg KH
2012-05-10 17:31 ` [ 26/52] sky2: propogate rx hash when packet is copied Greg KH
2012-05-10 17:31 ` [ 27/52] sky2: fix receive length error in mixed non-VLAN/VLAN traffic Greg KH
2012-05-10 17:32 ` [ 28/52] sungem: Fix WakeOnLan Greg KH
2012-05-10 17:32 ` [ 29/52] tg3: Avoid panic from reserved statblk field access Greg KH
2012-05-10 17:32 ` [ 30/52] tcp: fix infinite cwnd in tcp_complete_cwr() Greg KH
2012-05-10 17:32 ` [ 31/52] tcp: change tcp_adv_win_scale and tcp_rmem[2] Greg KH
2012-05-10 17:32 ` [ 32/52] net: Add memory barriers to prevent possible race in byte queue limits Greg KH
2012-05-10 17:32 ` [ 33/52] net: Fix issue with netdev_tx_reset_queue not resetting queue from XOFF state Greg KH
2012-05-10 18:53   ` Alexander Duyck
2012-05-10 18:55     ` David Miller
2012-05-10 19:46       ` Jonathan Nieder
2012-05-10 20:35         ` Alexander Duyck
2012-05-10 20:51           ` David Miller
2012-05-10 22:03             ` Greg KH
2012-05-10 17:32 ` [ 34/52] KVM: s390: do store status after handling STOP_ON_STOP bit Greg KH
2012-05-10 17:32 ` [ 35/52] KVM: s390: Sanitize fpc registers for KVM_SET_FPU Greg KH
2012-05-10 17:32 ` [ 36/52] KVM: Fix write protection race during dirty logging Greg KH
2012-05-10 17:32 ` [ 37/52] KVM: mmu_notifier: Flush TLBs before releasing mmu_lock Greg KH
2012-05-10 17:32 ` [ 38/52] KVM: x86 emulator: correctly mask pmc index bits in RDPMC instruction emulation Greg KH
2012-05-10 17:32 ` [ 39/52] KVM: Ensure all vcpus are consistent with in-kernel irqchip settings Greg KH
2012-05-10 17:32 ` [ 40/52] KVM: VMX: Fix delayed load of shared MSRs Greg KH
2012-05-10 17:32 ` [ 41/52] KVM: nVMX: Fix erroneous exception bitmap check Greg KH
2012-05-10 17:32 ` [ 42/52] KVM: VMX: vmx_set_cr0 expects kvm->srcu locked Greg KH
2012-05-10 17:32 ` [ 43/52] KVM: VMX: Fix kvm_set_shared_msr() called in preemptible context Greg KH
2012-05-10 17:32 ` [ 44/52] KVM: lock slots_lock around device assignment Greg KH
2012-05-10 17:32 ` [ 45/52] sony-laptop: Enable keyboard backlight by default Greg KH
2012-05-10 17:32 ` Greg KH [this message]
2012-05-10 17:32 ` [ 47/52] mtip32xx: fix incorrect value set for drv_cleanup_done, and re-initialize and start port in mtip_restart_port() Greg KH
2012-05-10 17:32 ` [ 48/52] mtip32xx: fix error handling in mtip_init() Greg KH
2012-05-10 17:32 ` [ 49/52] block: mtip32xx: remove HOTPLUG_PCI_PCIE dependancy Greg KH
2012-05-10 17:32 ` [ 50/52] nfsd: dont fail unchecked creates of non-special files Greg KH
2012-05-10 17:32 ` [ 51/52] ARM: 7397/1: l2x0: only apply workaround for erratum #753970 on PL310 Greg KH
2012-05-10 17:32 ` [ 52/52] ARM: 7398/1: l2x0: only write to debug registers " Greg KH

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=20120510173136.896369991@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=abarry@cray.com \
    --cc=akpm@linux-foundation.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=david@gibson.dropbear.id.au \
    --cc=dhillf@gmail.com \
    --cc=hughd@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mgorman@suse.de \
    --cc=minchan.kim@gmail.com \
    --cc=paulus@samba.org \
    --cc=stable@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    /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).