Skip to contentSkip to conversation

2.6.37.1-stable review

PATCH In review Greg KH 4 participants 280 messages Feb 16, 2011 Page 2 of 2

Subsystems (113)
lore
Share & tools
lore
author
#174 lore raw

PATCH 174/272 ARM: initrd: disable initrd if passed address overlaps reserved region

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Russell King <[email protected]>

commit b0a2679d27408d97ce31e5f800b44227d3388b84 upstream.

Disable the initrd if the passed address already overlaps the reserved region. This avoids oopses on Netwinders when NeTTrom tells the kernel that an initrd is located at mem+4MB, but this overlaps the BSS, resulting in the kernels in-use BSS being freed.

This should be applied to v2.6.37-stable.

---
 arch/arm/mm/init.c |    6 ++++++
 1 file changed, 6 insertions(+)
arch/arm/mm/init.c +6 -0
@@ -297,6 +297,12 @@ void __init arm_memblock_init(struct mem
 	memblock_reserve(__pa(_stext), _end - _stext);
 #endif
 #ifdef CONFIG_BLK_DEV_INITRD
+	if (phys_initrd_size &&
+	    memblock_is_region_reserved(phys_initrd_start, phys_initrd_size)) {
+		pr_err("INITRD: 0x%08lx+0x%08lx overlaps in-use memory region - disabling initrd\n",
+		       phys_initrd_start, phys_initrd_size);
+		phys_initrd_start = phys_initrd_size = 0;
+	}
 	if (phys_initrd_size) {
 		memblock_reserve(phys_initrd_start, phys_initrd_size);
 
author
#175 lore raw

PATCH 175/272 memcg: fix account leak at failure of memsw acconting

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: KAMEZAWA Hiroyuki <[email protected]>

commit 01c88e2d6b7330c0cc5867fe2297e7d826e1337d upstream.

Commit 4b53433468 ("memcg: clean up try_charge main loop") removes a cancel of charge at case: memory charge-> success. mem+swap charge-> failure.

This leaks usage of memory. Fix it.

---
 mm/memcontrol.c |    1 +
 1 file changed, 1 insertion(+)
mm/memcontrol.c +1 -0
@@ -1842,6 +1842,7 @@ static int __mem_cgroup_do_charge(struct
 		if (likely(!ret))
 			return CHARGE_OK;
 
+		res_counter_uncharge(&mem->res, csize);
 		mem_over_limit = mem_cgroup_from_res_counter(fail_res, memsw);
 		flags |= MEM_CGROUP_RECLAIM_NOSWAP;
 	} else
author
#176 lore raw

PATCH 176/272 mmc: bfin_sdh: fix alloc size for private data

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Sonic Zhang <[email protected]>

commit a34650f0f1ca589cda09c48cb62baf15e680a247 upstream.

The bfin_sdh driver allocates the wrong size for the private data in the mmc_host. The first parameter of mmc_alloc_host should be the size of the local driver struct rather than the common mmc_host.

---
 drivers/mmc/host/bfin_sdh.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mmc/host/bfin_sdh.c +1 -1
@@ -462,7 +462,7 @@ static int __devinit sdh_probe(struct pl
 		goto out;
 	}
 
-	mmc = mmc_alloc_host(sizeof(*mmc), &pdev->dev);
+	mmc = mmc_alloc_host(sizeof(struct sdh_host), &pdev->dev);
 	if (!mmc) {
 		ret = -ENOMEM;
 		goto out;
author
#177 lore raw

PATCH 177/272 Revert "exofs: Set i_mapping->backing_dev_info anyway"

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Boaz Harrosh <[email protected]>

commit 0b0abeaf3d30cec03ac6497fe978b8f7edecc5ae upstream.

This reverts commit 115e19c53501edc11f730191f7f047736815ae3d.

Apparently setting inode->bdi to one's own sb->s_bdi stops VFS from sending *read-aheads*. This problem was bisected to this commit. A revert fixes it. I'll investigate farther why is this happening for the next Kernel, but for now a revert.

I'm sending to [email protected] as well, since it exists also in 2.6.37. 2.6.36 is good and does not have this patch.

---
 fs/exofs/inode.c |    2 --
 1 file changed, 2 deletions(-)
fs/exofs/inode.c +0 -2
@@ -1030,7 +1030,6 @@ struct inode *exofs_iget(struct super_bl
 		memcpy(oi->i_data, fcb.i_data, sizeof(fcb.i_data));
 	}
 
-	inode->i_mapping->backing_dev_info = sb->s_bdi;
 	if (S_ISREG(inode->i_mode)) {
 		inode->i_op = &exofs_file_inode_operations;
 		inode->i_fop = &exofs_file_operations;
@@ -1131,7 +1130,6 @@ struct inode *exofs_new_inode(struct ino
 
 	sbi = sb->s_fs_info;
 
-	inode->i_mapping->backing_dev_info = sb->s_bdi;
 	sb->s_dirt = 1;
 	inode_init_owner(inode, dir, mode);
 	inode->i_ino = sbi->s_nextid++;
author
#178 lore raw

PATCH 178/272 slub: Avoid use of slub_lock in show_slab_objects()

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Christoph Lameter <[email protected]>

commit 04d94879c8a4973b5499dc26b9d38acee8928791 upstream.

The purpose of the locking is to prevent removal and additions of nodes when statistics are gathered for a slab cache. So we need to avoid racing with memory hotplug functionality.

It is enough to take the memory hotplug locks there instead of the slub_lock.

online_pages() currently does not acquire the memory_hotplug lock. Another patch will be submitted by the memory hotplug authors to take the memory hotplug lock and describe the uses of the memory hotplug lock to protect against adding and removal of nodes from non hotplug data structures.

---
 mm/slub.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
mm/slub.c +2 -2
@@ -3821,7 +3821,7 @@ static ssize_t show_slab_objects(struct
 		}
 	}
 
-	down_read(&slub_lock);
+	lock_memory_hotplug();
 #ifdef CONFIG_SLUB_DEBUG
 	if (flags & SO_ALL) {
 		for_each_node_state(node, N_NORMAL_MEMORY) {
@@ -3862,7 +3862,7 @@ static ssize_t show_slab_objects(struct
 			x += sprintf(buf + x, " N%d=%lu",
 					node, nodes[node]);
 #endif
-	up_read(&slub_lock);
+	unlock_memory_hotplug();
 	kfree(nodes);
 	return x + sprintf(buf + x, "\n");
 }
author
#179 lore raw

PATCH 179/272 x86, olpc: Add missing Kconfig dependencies

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: H. Peter Anvin <[email protected]>

commit 76d1f7bfcd5872056902c5a88b5fcd5d4d00a7a9 upstream.

OLPC uses select for OLPC_OPENFIRMWARE, which means OLPC has to enforce the dependencies for OLPC_OPENFIRMWARE. Make sure it does so.

Cc Daniel Drake <[email protected]>
Cc Andres Salomon <[email protected]>
Cc Grant Likely <[email protected]>

LKML-Reference: <[email protected]>

---
 arch/x86/Kconfig |    1 +
 1 file changed, 1 insertion(+)
arch/x86/Kconfig +1 -0
@@ -2035,6 +2035,7 @@ config OLPC
 	bool "One Laptop Per Child support"
 	select GPIOLIB
 	select OLPC_OPENFIRMWARE
+	depends on !X86_64 && !X86_PAE
 	---help---
 	  Add support for detecting the unique features of the OLPC
 	  XO hardware.
author
#180 lore raw

PATCH 180/272 net: ax25: fix information leak to userland harder

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Kees Cook <[email protected]>

commit 5b919f833d9d60588d026ad82d17f17e8872c7a9 upstream.

Commit fe10ae53384e48c51996941b7720ee16995cbcb7 adds a memset() to clear the structure being sent back to userspace, but accidentally used the wrong size.

---
 net/ax25/af_ax25.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/ax25/af_ax25.c +1 -1
@@ -1392,7 +1392,7 @@ static int ax25_getname(struct socket *s
 	ax25_cb *ax25;
 	int err = 0;
 
-	memset(fsa, 0, sizeof(fsa));
+	memset(fsa, 0, sizeof(*fsa));
 	lock_sock(sk);
 	ax25 = ax25_sk(sk);
 
author
#181 lore raw

PATCH 181/272 xen-platform: use PCI interfaces to request IO and MEM resources.

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Ian Campbell <[email protected]>

commit 00f28e4037c8d5782fa7a1b2666b0dca21522d69 upstream.

This is the correct interface to use and something has broken the use of the previous incorrect interface (which fails because the request conflicts with the resources assigned for the PCI device itself instead of nesting like the PCI interfaces do).

---
 drivers/xen/platform-pci.c |   21 +++++++--------------
 1 file changed, 7 insertions(+), 14 deletions(-)
drivers/xen/platform-pci.c +7 -14
@@ -105,7 +105,7 @@ static int __devinit platform_pci_init(s
 				       const struct pci_device_id *ent)
 {
 	int i, ret;
-	long ioaddr, iolen;
+	long ioaddr;
 	long mmio_addr, mmio_len;
 	unsigned int max_nr_gframes;
 
@@ -114,7 +114,6 @@ static int __devinit platform_pci_init(s
 		return i;
 
 	ioaddr = pci_resource_start(pdev, 0);
-	iolen = pci_resource_len(pdev, 0);
 
 	mmio_addr = pci_resource_start(pdev, 1);
 	mmio_len = pci_resource_len(pdev, 1);
@@ -125,19 +124,13 @@ static int __devinit platform_pci_init(s
 		goto pci_out;
 	}
 
-	if (request_mem_region(mmio_addr, mmio_len, DRV_NAME) == NULL) {
-		dev_err(&pdev->dev, "MEM I/O resource 0x%lx @ 0x%lx busy\n",
-		       mmio_addr, mmio_len);
-		ret = -EBUSY;
+	ret = pci_request_region(pdev, 1, DRV_NAME);
+	if (ret < 0)
 		goto pci_out;
-	}
 
-	if (request_region(ioaddr, iolen, DRV_NAME) == NULL) {
-		dev_err(&pdev->dev, "I/O resource 0x%lx @ 0x%lx busy\n",
-		       iolen, ioaddr);
-		ret = -EBUSY;
+	ret = pci_request_region(pdev, 0, DRV_NAME);
+	if (ret < 0)
 		goto mem_out;
-	}
 
 	platform_mmio = mmio_addr;
 	platform_mmiolen = mmio_len;
@@ -169,9 +162,9 @@ static int __devinit platform_pci_init(s
 	return 0;
 
 out:
-	release_region(ioaddr, iolen);
+	pci_release_region(pdev, 0);
 mem_out:
-	release_mem_region(mmio_addr, mmio_len);
+	pci_release_region(pdev, 1);
 pci_out:
 	pci_disable_device(pdev);
 	return ret;
author
#182 lore raw

PATCH 182/272 mm: page allocator: adjust the per-cpu counter threshold when memory is low

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Mel Gorman <[email protected]>

commit 88f5acf88ae6a9778f6d25d0d5d7ec2d57764a97 upstream.

Commit aa45484 ("calculate a better estimate of NR_FREE_PAGES when memory is low") noted that watermarks were based on the vmstat NR_FREE_PAGES. To avoid synchronization overhead, these counters are maintained on a per-cpu basis and drained both periodically and when a threshold is above a threshold. On large CPU systems, the difference between the estimate and real value of NR_FREE_PAGES can be very high. The system can get into a case where pages are allocated far below the min watermark potentially causing livelock issues. The commit solved the problem by taking a better reading of NR_FREE_PAGES when memory was low.

Unfortately, as reported by Shaohua Li this accurate reading can consume a large amount of CPU time on systems with many sockets due to cache line bouncing. This patch takes a different approach. For large machines where counter drift might be unsafe and while kswapd is awake, the per-cpu thresholds for the target pgdat are reduced to limit the level of drift to what should be a safe level. This incurs a performance penalty in heavy memory pressure by a factor that depends on the workload and the machine but the machine should function correctly without accidentally exhausting all memory on a node. There is an additional cost when kswapd wakes and sleeps but the event is not expected to be frequent - in Shaohua's test case, there was one recorded sleep and wake event at least.

To ensure that kswapd wakes up, a safe version of zone_watermark_ok() is introduced that takes a more accurate reading of NR_FREE_PAGES when called from wakeup_kswapd, when deciding whether it is really safe to go back to sleep in sleeping_prematurely() and when deciding if a zone is really balanced or not in balance_pgdat(). We are still using an expensive function but limiting how often it is called.

When the test case is reproduced, the time spent in the watermark functions is reduced. The following report is on the percentage of time spent cumulatively spent in the functions zone_nr_free_pages(), zone_watermark_ok(), __zone_watermark_ok(), zone_watermark_ok_safe(), zone_page_state_snapshot(), zone_page_state().

vanilla 11.6615%
disable-threshold 0.2584%

David said:

: We had to pull aa454840 "mm: page allocator: calculate a better estimate : of NR_FREE_PAGES when memory is low and kswapd is awake" from 2.6.36 : internally because tests showed that it would cause the machine to stall : as the result of heavy kswapd activity. I merged it back with this fix as : it is pending in the -mm tree and it solves the issue we were seeing, so I : definitely think this should be pushed to -stable (and I would seriously : consider it for 2.6.37 inclusion even at this late date).

---
 include/linux/mmzone.h |   10 ++-----
 include/linux/vmstat.h |    5 +++
 mm/mmzone.c            |   21 ---------------
 mm/page_alloc.c        |   35 +++++++++++++++++++------
 mm/vmscan.c            |   23 +++++++++-------
 mm/vmstat.c            |   68 ++++++++++++++++++++++++++++++++++++++++++++++++-
 6 files changed, 115 insertions(+), 47 deletions(-)
include/linux/mmzone.h +3 -7
@@ -458,12 +458,6 @@ static inline int zone_is_oom_locked(con
 	return test_bit(ZONE_OOM_LOCKED, &zone->flags);
 }
 
-#ifdef CONFIG_SMP
-unsigned long zone_nr_free_pages(struct zone *zone);
-#else
-#define zone_nr_free_pages(zone) zone_page_state(zone, NR_FREE_PAGES)
-#endif /* CONFIG_SMP */
-
 /*
  * The "priority" of VM scanning is how much of the queues we will scan in one
  * go. A value of 12 for DEF_PRIORITY implies that we will scan 1/4096th of the
@@ -661,7 +655,9 @@ typedef struct pglist_data {
 extern struct mutex zonelists_mutex;
 void build_all_zonelists(void *data);
 void wakeup_kswapd(struct zone *zone, int order);
-int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
+bool zone_watermark_ok(struct zone *z, int order, unsigned long mark,
+		int classzone_idx, int alloc_flags);
+bool zone_watermark_ok_safe(struct zone *z, int order, unsigned long mark,
 		int classzone_idx, int alloc_flags);
 enum memmap_context {
 	MEMMAP_EARLY,
include/linux/vmstat.h +5 -0
@@ -254,6 +254,8 @@ extern void dec_zone_state(struct zone *
 extern void __dec_zone_state(struct zone *, enum zone_stat_item);
 
 void refresh_cpu_vm_stats(int);
+void reduce_pgdat_percpu_threshold(pg_data_t *pgdat);
+void restore_pgdat_percpu_threshold(pg_data_t *pgdat);
 #else /* CONFIG_SMP */
 
 /*
@@ -298,6 +300,9 @@ static inline void __dec_zone_page_state
 #define dec_zone_page_state __dec_zone_page_state
 #define mod_zone_page_state __mod_zone_page_state
 
+static inline void reduce_pgdat_percpu_threshold(pg_data_t *pgdat) { }
+static inline void restore_pgdat_percpu_threshold(pg_data_t *pgdat) { }
+
 static inline void refresh_cpu_vm_stats(int cpu) { }
 #endif
 
mm/mmzone.c +0 -21
@@ -87,24 +87,3 @@ int memmap_valid_within(unsigned long pf
 	return 1;
 }
 #endif /* CONFIG_ARCH_HAS_HOLES_MEMORYMODEL */
-
-#ifdef CONFIG_SMP
-/* Called when a more accurate view of NR_FREE_PAGES is needed */
-unsigned long zone_nr_free_pages(struct zone *zone)
-{
-	unsigned long nr_free_pages = zone_page_state(zone, NR_FREE_PAGES);
-
-	/*
-	 * While kswapd is awake, it is considered the zone is under some
-	 * memory pressure. Under pressure, there is a risk that
-	 * per-cpu-counter-drift will allow the min watermark to be breached
-	 * potentially causing a live-lock. While kswapd is awake and
-	 * free pages are low, get a better estimate for free pages
-	 */
-	if (nr_free_pages < zone->percpu_drift_mark &&
-			!waitqueue_active(&zone->zone_pgdat->kswapd_wait))
-		return zone_page_state_snapshot(zone, NR_FREE_PAGES);
-
-	return nr_free_pages;
-}
-#endif /* CONFIG_SMP */
mm/page_alloc.c +27 -8
@@ -1460,24 +1460,24 @@ static inline int should_fail_alloc_page
 #endif /* CONFIG_FAIL_PAGE_ALLOC */
 
 /*
- * Return 1 if free pages are above 'mark'. This takes into account the order
+ * Return true if free pages are above 'mark'. This takes into account the order
  * of the allocation.
  */
-int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
-		      int classzone_idx, int alloc_flags)
+static bool __zone_watermark_ok(struct zone *z, int order, unsigned long mark,
+		      int classzone_idx, int alloc_flags, long free_pages)
 {
 	/* free_pages my go negative - that's OK */
 	long min = mark;
-	long free_pages = zone_nr_free_pages(z) - (1 << order) + 1;
 	int o;
 
+	free_pages -= (1 << order) + 1;
 	if (alloc_flags & ALLOC_HIGH)
 		min -= min / 2;
 	if (alloc_flags & ALLOC_HARDER)
 		min -= min / 4;
 
 	if (free_pages <= min + z->lowmem_reserve[classzone_idx])
-		return 0;
+		return false;
 	for (o = 0; o < order; o++) {
 		/* At the next order, this order's pages become unavailable */
 		free_pages -= z->free_area[o].nr_free << o;
@@ -1486,9 +1486,28 @@ int zone_watermark_ok(struct zone *z, in
 		min >>= 1;
 
 		if (free_pages <= min)
-			return 0;
+			return false;
 	}
-	return 1;
+	return true;
+}
+
+bool zone_watermark_ok(struct zone *z, int order, unsigned long mark,
+		      int classzone_idx, int alloc_flags)
+{
+	return __zone_watermark_ok(z, order, mark, classzone_idx, alloc_flags,
+					zone_page_state(z, NR_FREE_PAGES));
+}
+
+bool zone_watermark_ok_safe(struct zone *z, int order, unsigned long mark,
+		      int classzone_idx, int alloc_flags)
+{
+	long free_pages = zone_page_state(z, NR_FREE_PAGES);
+
+	if (z->percpu_drift_mark && free_pages < z->percpu_drift_mark)
+		free_pages = zone_page_state_snapshot(z, NR_FREE_PAGES);
+
+	return __zone_watermark_ok(z, order, mark, classzone_idx, alloc_flags,
+								free_pages);
 }
 
 #ifdef CONFIG_NUMA
@@ -2442,7 +2461,7 @@ void show_free_areas(void)
 			" all_unreclaimable? %s"
 			"\n",
 			zone->name,
-			K(zone_nr_free_pages(zone)),
+			K(zone_page_state(zone, NR_FREE_PAGES)),
 			K(min_wmark_pages(zone)),
 			K(low_wmark_pages(zone)),
 			K(high_wmark_pages(zone)),
mm/vmscan.c +13 -10
@@ -2143,7 +2143,7 @@ static int sleeping_prematurely(pg_data_
 		if (zone->all_unreclaimable)
 			continue;
 
-		if (!zone_watermark_ok(zone, order, high_wmark_pages(zone),
+		if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone),
 								0, 0))
 			return 1;
 	}
@@ -2230,7 +2230,7 @@ loop_again:
 				shrink_active_list(SWAP_CLUSTER_MAX, zone,
 							&sc, priority, 0);
 
-			if (!zone_watermark_ok(zone, order,
+			if (!zone_watermark_ok_safe(zone, order,
 					high_wmark_pages(zone), 0, 0)) {
 				end_zone = i;
 				break;
@@ -2276,7 +2276,7 @@ loop_again:
 			 * We put equal pressure on every zone, unless one
 			 * zone has way too many pages free already.
 			 */
-			if (!zone_watermark_ok(zone, order,
+			if (!zone_watermark_ok_safe(zone, order,
 					8*high_wmark_pages(zone), end_zone, 0))
 				shrink_zone(priority, zone, &sc);
 			reclaim_state->reclaimed_slab = 0;
@@ -2297,7 +2297,7 @@ loop_again:
 			    total_scanned > sc.nr_reclaimed + sc.nr_reclaimed / 2)
 				sc.may_writepage = 1;
 
-			if (!zone_watermark_ok(zone, order,
+			if (!zone_watermark_ok_safe(zone, order,
 					high_wmark_pages(zone), end_zone, 0)) {
 				all_zones_ok = 0;
 				/*
@@ -2305,7 +2305,7 @@ loop_again:
 				 * means that we have a GFP_ATOMIC allocation
 				 * failure risk. Hurry up!
 				 */
-				if (!zone_watermark_ok(zone, order,
+				if (!zone_watermark_ok_safe(zone, order,
 					    min_wmark_pages(zone), end_zone, 0))
 					has_under_min_watermark_zone = 1;
 			} else {
@@ -2448,7 +2448,9 @@ static int kswapd(void *p)
 				 */
 				if (!sleeping_prematurely(pgdat, order, remaining)) {
 					trace_mm_vmscan_kswapd_sleep(pgdat->node_id);
+					restore_pgdat_percpu_threshold(pgdat);
 					schedule();
+					reduce_pgdat_percpu_threshold(pgdat);
 				} else {
 					if (remaining)
 						count_vm_event(KSWAPD_LOW_WMARK_HIT_QUICKLY);
@@ -2487,16 +2489,17 @@ void wakeup_kswapd(struct zone *zone, in
 	if (!populated_zone(zone))
 		return;
 
-	pgdat = zone->zone_pgdat;
-	if (zone_watermark_ok(zone, order, low_wmark_pages(zone), 0, 0))
+	if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
 		return;
+	pgdat = zone->zone_pgdat;
 	if (pgdat->kswapd_max_order < order)
 		pgdat->kswapd_max_order = order;
-	trace_mm_vmscan_wakeup_kswapd(pgdat->node_id, zone_idx(zone), order);
-	if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
-		return;
 	if (!waitqueue_active(&pgdat->kswapd_wait))
 		return;
+	if (zone_watermark_ok_safe(zone, order, low_wmark_pages(zone), 0, 0))
+		return;
+
+	trace_mm_vmscan_wakeup_kswapd(pgdat->node_id, zone_idx(zone), order);
 	wake_up_interruptible(&pgdat->kswapd_wait);
 }
 
mm/vmstat.c +67 -1

86 lines not on this page · raw message

author
#183 lore raw

PATCH 183/272 klist: Fix object alignment on 64-bit.

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: David Miller <[email protected]>

commit 795abaf1e4e188c4171e3cd3dbb11a9fcacaf505 upstream.

Commit c0e69a5bbc6f ("klist.c: bit 0 in pointer can't be used as flag") intended to make sure that all klist objects were at least pointer size aligned, but used the constant "4" which only works on 32-bit.

Use "sizeof(void *)" which is correct in all cases.

---
 include/linux/klist.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/klist.h +1 -1
@@ -22,7 +22,7 @@ struct klist {
 	struct list_head	k_list;
 	void			(*get)(struct klist_node *);
 	void			(*put)(struct klist_node *);
-} __attribute__ ((aligned (4)));
+} __attribute__ ((aligned (sizeof(void *))));
 
 #define KLIST_INIT(_name, _get, _put)					\
 	{ .k_lock	= __SPIN_LOCK_UNLOCKED(_name.k_lock),		\
author
#184 lore raw

PATCH 184/272 epoll: epoll_wait() should not use timespec_add_ns()

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Eric Dumazet <[email protected]>

commit 0781b909b5586f4db720b5d1838b78f9d8e42f14 upstream.

commit 95aac7b1cd224f ("epoll: make epoll_wait() use the hrtimer range feature") added a performance regression because it uses timespec_add_ns() with potential very large 'ns' values.

---
 fs/eventpoll.c |   16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)
fs/eventpoll.c +13 -3
@@ -1111,6 +1111,17 @@ static int ep_send_events(struct eventpo
 	return ep_scan_ready_list(ep, ep_send_events_proc, &esed);
 }
 
+static inline struct timespec ep_set_mstimeout(long ms)
+{
+	struct timespec now, ts = {
+		.tv_sec = ms / MSEC_PER_SEC,
+		.tv_nsec = NSEC_PER_MSEC * (ms % MSEC_PER_SEC),
+	};
+
+	ktime_get_ts(&now);
+	return timespec_add_safe(now, ts);
+}
+
 static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
 		   int maxevents, long timeout)
 {
@@ -1118,12 +1129,11 @@ static int ep_poll(struct eventpoll *ep,
 	unsigned long flags;
 	long slack;
 	wait_queue_t wait;
-	struct timespec end_time;
 	ktime_t expires, *to = NULL;
 
 	if (timeout > 0) {
-		ktime_get_ts(&end_time);
-		timespec_add_ns(&end_time, (u64)timeout * NSEC_PER_MSEC);
+		struct timespec end_time = ep_set_mstimeout(timeout);
+
 		slack = select_estimate_accuracy(&end_time);
 		to = &expires;
 		*to = timespec_to_ktime(end_time);
author
#185 lore raw

PATCH 185/272 sched: Change wait_for_completion_*_timeout() to return a signed long

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: NeilBrown <[email protected]>

commit 6bf4123760a5aece6e4829ce90b70b6ffd751d65 upstream.

wait_for_completion_*_timeout() can return:

0: if the wait timed out
-ve: if the wait was interrupted
+ve: if the completion was completed.

As they currently return an 'unsigned long', the last two cases are not easily distinguished which can easily result in buggy code, as is the case for the recently added wait_for_completion_interruptible_timeout() call in net/sunrpc/cache.c

So change them both to return 'long'. As MAX_SCHEDULE_TIMEOUT is LONG_MAX, a large +ve return value should never overflow.

Cc Peter Zijlstra <[email protected]>
Cc J. Bruce Fields <[email protected]>
Cc Andrew Morton <[email protected]>
Cc Linus Torvalds <[email protected]>

LKML-Reference: <[email protected]>

---
 include/linux/completion.h |    8 ++++----
 kernel/sched.c             |    4 ++--
 2 files changed, 6 insertions(+), 6 deletions(-)
include/linux/completion.h +4 -4
@@ -81,10 +81,10 @@ extern int wait_for_completion_interrupt
 extern int wait_for_completion_killable(struct completion *x);
 extern unsigned long wait_for_completion_timeout(struct completion *x,
 						   unsigned long timeout);
-extern unsigned long wait_for_completion_interruptible_timeout(
-			struct completion *x, unsigned long timeout);
-extern unsigned long wait_for_completion_killable_timeout(
-			struct completion *x, unsigned long timeout);
+extern long wait_for_completion_interruptible_timeout(
+	struct completion *x, unsigned long timeout);
+extern long wait_for_completion_killable_timeout(
+	struct completion *x, unsigned long timeout);
 extern bool try_wait_for_completion(struct completion *x);
 extern bool completion_done(struct completion *x);
 
kernel/sched.c +2 -2
@@ -4526,7 +4526,7 @@ EXPORT_SYMBOL(wait_for_completion_interr
  * This waits for either a completion of a specific task to be signaled or for a
  * specified timeout to expire. It is interruptible. The timeout is in jiffies.
  */
-unsigned long __sched
+long __sched
 wait_for_completion_interruptible_timeout(struct completion *x,
 					  unsigned long timeout)
 {
@@ -4559,7 +4559,7 @@ EXPORT_SYMBOL(wait_for_completion_killab
  * signaled or for a specified timeout to expire. It can be
  * interrupted by a kill signal. The timeout is in jiffies.
  */
-unsigned long __sched
+long __sched
 wait_for_completion_killable_timeout(struct completion *x,
 				     unsigned long timeout)
 {
author
#186 lore raw

PATCH 186/272 sched, cgroup: Use exit hook to avoid use-after-free crash

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Peter Zijlstra <[email protected]>

commit 068c5cc5ac7414a8e9eb7856b4bf3cc4d4744267 upstream.

By not notifying the controller of the on-exit move back to init_css_set, we fail to move the task out of the previous cgroup's cfs_rq. This leads to an opportunity for a cgroup-destroy to come in and free the cgroup (there are no active tasks left in it after all) to which the not-quite dead task is still enqueued.

LKML-Reference: <1293206353.29444.205.camel@laptop>

---
 kernel/sched.c |   18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
kernel/sched.c +18 -0
@@ -607,6 +607,9 @@ static inline struct task_group *task_gr
 {
 	struct cgroup_subsys_state *css;
 
+	if (p->flags & PF_EXITING)
+		return &root_task_group;
+
 	css = task_subsys_state_check(p, cpu_cgroup_subsys_id,
 			lockdep_is_held(&task_rq(p)->lock));
 	return container_of(css, struct task_group, css);
@@ -9178,6 +9181,20 @@ cpu_cgroup_attach(struct cgroup_subsys *
 	}
 }
 
+static void
+cpu_cgroup_exit(struct cgroup_subsys *ss, struct task_struct *task)
+{
+	/*
+	 * cgroup_exit() is called in the copy_process() failure path.
+	 * Ignore this case since the task hasn't ran yet, this avoids
+	 * trying to poke a half freed task state from generic code.
+	 */
+	if (!(task->flags & PF_EXITING))
+		return;
+
+	sched_move_task(task);
+}
+
 #ifdef CONFIG_FAIR_GROUP_SCHED
 static int cpu_shares_write_u64(struct cgroup *cgrp, struct cftype *cftype,
 				u64 shareval)
@@ -9250,6 +9267,7 @@ struct cgroup_subsys cpu_cgroup_subsys =
 	.destroy	= cpu_cgroup_destroy,
 	.can_attach	= cpu_cgroup_can_attach,
 	.attach		= cpu_cgroup_attach,
+	.exit		= cpu_cgroup_exit,
 	.populate	= cpu_cgroup_populate,
 	.subsys_id	= cpu_cgroup_subsys_id,
 	.early_init	= 1,
author
#187 lore raw

PATCH 187/272 sched: Fix update_curr_rt()

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Peter Zijlstra <[email protected]>

commit 06c3bc655697b19521901f9254eb0bbb2c67e7e8 upstream.

cpu_stopper_thread()
migration_cpu_stop()

    __migrate_task()
      deactivate_task()
        dequeue_task()
          dequeue_task_rq()
            update_curr_rt()

Will call update_curr_rt() on rq->curr, which at that time is rq->stop. The problem is that rq->stop.prio matches an RT prio and thus falsely assumes its a rt_sched_class task.

LKML-Reference: <new-submission>

---
 kernel/sched_rt.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/sched_rt.c +1 -1
@@ -606,7 +606,7 @@ static void update_curr_rt(struct rq *rq
 	struct rt_rq *rt_rq = rt_rq_of_se(rt_se);
 	u64 delta_exec;
 
-	if (!task_has_rt_policy(curr))
+	if (curr->sched_class != &rt_sched_class)
 		return;
 
 	delta_exec = rq->clock_task - curr->se.exec_start;
author
#188 lore raw

PATCH 188/272 cfq-iosched: Dont wait if queue already has requests.

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Justin TerAvest <[email protected]>

commit 02a8f01b5a9f396d0327977af4c232d0f94c45fd upstream.

Commit 7667aa0630407bc07dc38dcc79d29cc0a65553c1 added logic to wait for the last queue of the group to become busy (have at least one request), so that the group does not lose out for not being continuously backlogged. The commit did not check for the condition that the last queue already has some requests. As a result, if the queue already has requests, wait_busy is set. Later on, cfq_select_queue() checks the flag, and decides that since the queue has a request now and wait_busy is set, the queue is expired. This results in early expiration of the queue.

This patch fixes the problem by adding a check to see if queue already has requests. If it does, wait_busy is not set. As a result, time slices do not expire early.

The queues with more than one request are usually buffered writers. Testing shows improvement in isolation between buffered writers.

---
 block/cfq-iosched.c |    4 ++++
 1 file changed, 4 insertions(+)
block/cfq-iosched.c +4 -0
@@ -3412,6 +3412,10 @@ static bool cfq_should_wait_busy(struct
 {
 	struct cfq_io_context *cic = cfqd->active_cic;
 
+	/* If the queue already has requests, don't wait */
+	if (!RB_EMPTY_ROOT(&cfqq->sort_list))
+		return false;
+
 	/* If there are other queues in the group, don't wait */
 	if (cfqq->cfqg->nr_cfqq > 1)
 		return false;
author
#189 lore raw

PATCH 189/272 powerpc/85xx: fix compatible properties of the P1022DS DMA nodes used for audio

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Timur Tabi <[email protected]>

commit b2e0861e51f2961954330dcafe6d148ee3ab5cff upstream.

In order to prevent the fsl_dma driver from claiming the DMA channels that the P1022DS audio driver needs, the compatible properties for those nodes must say "fsl,ssi-dma-channel" instead of "fsl,eloplus-dma-channel".

---
 arch/powerpc/boot/dts/p1022ds.dts |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/powerpc/boot/dts/p1022ds.dts +2 -2
@@ -291,13 +291,13 @@
 			ranges = <0x0 0xc100 0x200>;
 			cell-index = <1>;
 			dma00: dma-channel@0 {
-				compatible = "fsl,eloplus-dma-channel";
+				compatible = "fsl,ssi-dma-channel";
 				reg = <0x0 0x80>;
 				cell-index = <0>;
 				interrupts = <76 2>;
 			};
 			dma01: dma-channel@80 {
-				compatible = "fsl,eloplus-dma-channel";
+				compatible = "fsl,ssi-dma-channel";
 				reg = <0x80 0x80>;
 				cell-index = <1>;
 				interrupts = <77 2>;
author
#190 lore raw

PATCH 190/272 powerpc: Fix hcall tracepoint recursion

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Anton Blanchard <[email protected]>

commit 57cdfdf829a850a317425ed93c6a576c9ee6329c upstream.

Spinlocks on shared processor partitions use H_YIELD to notify the hypervisor we are waiting on another virtual CPU. Unfortunately this means the hcall tracepoints can recurse.

The patch below adds a percpu depth and checks it on both the entry and exit hcall tracepoints.

---
 arch/powerpc/platforms/pseries/lpar.c |   37 ++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
arch/powerpc/platforms/pseries/lpar.c +37 -0
@@ -701,6 +701,13 @@ EXPORT_SYMBOL(arch_free_page);
 /* NB: reg/unreg are called while guarded with the tracepoints_mutex */
 extern long hcall_tracepoint_refcount;
 
+/*
+ * Since the tracing code might execute hcalls we need to guard against
+ * recursion. One example of this are spinlocks calling H_YIELD on
+ * shared processor partitions.
+ */
+static DEFINE_PER_CPU(unsigned int, hcall_trace_depth);
+
 void hcall_tracepoint_regfunc(void)
 {
 	hcall_tracepoint_refcount++;
@@ -713,12 +720,42 @@ void hcall_tracepoint_unregfunc(void)
 
 void __trace_hcall_entry(unsigned long opcode, unsigned long *args)
 {
+	unsigned long flags;
+	unsigned int *depth;
+
+	local_irq_save(flags);
+
+	depth = &__get_cpu_var(hcall_trace_depth);
+
+	if (*depth)
+		goto out;
+
+	(*depth)++;
 	trace_hcall_entry(opcode, args);
+	(*depth)--;
+
+out:
+	local_irq_restore(flags);
 }
 
 void __trace_hcall_exit(long opcode, unsigned long retval,
 			unsigned long *retbuf)
 {
+	unsigned long flags;
+	unsigned int *depth;
+
+	local_irq_save(flags);
+
+	depth = &__get_cpu_var(hcall_trace_depth);
+
+	if (*depth)
+		goto out;
+
+	(*depth)++;
 	trace_hcall_exit(opcode, retval, retbuf);
+	(*depth)--;
+
+out:
+	local_irq_restore(flags);
 }
 #endif
author
#191 lore raw

PATCH 191/272 powerpc/numa: Fix bug in unmap_cpu_from_node

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Anton Blanchard <[email protected]>

commit 429f4d8d20b91e4a6c239f951c06a56a6ac22957 upstream.

When converting to the new cpumask code I screwed up:

- if (cpu_isset(cpu, numa_cpumask_lookup_table[node])) {
- cpu_clear(cpu, numa_cpumask_lookup_table[node]);
+ if (cpumask_test_cpu(cpu, node_to_cpumask_map[node])) {
+ cpumask_set_cpu(cpu, node_to_cpumask_map[node]);

This was introduced in commit 25863de07af9 (powerpc/cpumask: Convert NUMA code to new cpumask API)

Fix it.

---
 arch/powerpc/mm/numa.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/mm/numa.c +1 -1
@@ -181,7 +181,7 @@ static void unmap_cpu_from_node(unsigned
 	dbg("removing cpu %lu from node %d\n", cpu, node);
 
 	if (cpumask_test_cpu(cpu, node_to_cpumask_map[node])) {
-		cpumask_set_cpu(cpu, node_to_cpumask_map[node]);
+		cpumask_clear_cpu(cpu, node_to_cpumask_map[node]);
 	} else {
 		printk(KERN_ERR "WARNING: cpu %lu not found in node %d\n",
 		       cpu, node);
author
#192 lore raw

PATCH 192/272 powerpc: Fix some 6xx/7xxx CPU setup functions

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Benjamin Herrenschmidt <[email protected]>

commit 1f1936ff3febf38d582177ea319eaa278f32c91f upstream.

Some of those functions try to adjust the CPU features, for example to remove NAP support on some revisions. However, they seem to use r5 as an index into the CPU table entry, which might have been right a long time ago but no longer is. r4 is the right register to use.

This probably caused some off behaviours on some PowerMac variants using 750cx or 7455 processor revisions.

---
 arch/powerpc/kernel/cpu_setup_6xx.S |   40 ++++++++++++++++++------------------
 1 file changed, 20 insertions(+), 20 deletions(-)
arch/powerpc/kernel/cpu_setup_6xx.S +20 -20
@@ -18,7 +18,7 @@
 #include <asm/mmu.h>
 
 _GLOBAL(__setup_cpu_603)
-	mflr	r4
+	mflr	r5
 BEGIN_MMU_FTR_SECTION
 	li	r10,0
 	mtspr	SPRN_SPRG_603_LRU,r10		/* init SW LRU tracking */
@@ -27,60 +27,60 @@ BEGIN_FTR_SECTION
 	bl	__init_fpu_registers
 END_FTR_SECTION_IFCLR(CPU_FTR_FPU_UNAVAILABLE)
 	bl	setup_common_caches
-	mtlr	r4
+	mtlr	r5
 	blr
 _GLOBAL(__setup_cpu_604)
-	mflr	r4
+	mflr	r5
 	bl	setup_common_caches
 	bl	setup_604_hid0
-	mtlr	r4
+	mtlr	r5
 	blr
 _GLOBAL(__setup_cpu_750)
-	mflr	r4
+	mflr	r5
 	bl	__init_fpu_registers
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
-	mtlr	r4
+	mtlr	r5
 	blr
 _GLOBAL(__setup_cpu_750cx)
-	mflr	r4
+	mflr	r5
 	bl	__init_fpu_registers
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
 	bl	setup_750cx
-	mtlr	r4
+	mtlr	r5
 	blr
 _GLOBAL(__setup_cpu_750fx)
-	mflr	r4
+	mflr	r5
 	bl	__init_fpu_registers
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
 	bl	setup_750fx
-	mtlr	r4
+	mtlr	r5
 	blr
 _GLOBAL(__setup_cpu_7400)
-	mflr	r4
+	mflr	r5
 	bl	__init_fpu_registers
 	bl	setup_7400_workarounds
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
-	mtlr	r4
+	mtlr	r5
 	blr
 _GLOBAL(__setup_cpu_7410)
-	mflr	r4
+	mflr	r5
 	bl	__init_fpu_registers
 	bl	setup_7410_workarounds
 	bl	setup_common_caches
 	bl	setup_750_7400_hid0
 	li	r3,0
 	mtspr	SPRN_L2CR2,r3
-	mtlr	r4
+	mtlr	r5
 	blr
 _GLOBAL(__setup_cpu_745x)
-	mflr	r4
+	mflr	r5
 	bl	setup_common_caches
 	bl	setup_745x_specifics
-	mtlr	r4
+	mtlr	r5
 	blr
 
 /* Enable caches for 603's, 604, 750 & 7400 */
@@ -194,10 +194,10 @@ setup_750cx:
 	cror	4*cr0+eq,4*cr0+eq,4*cr1+eq
 	cror	4*cr0+eq,4*cr0+eq,4*cr2+eq
 	bnelr
-	lwz	r6,CPU_SPEC_FEATURES(r5)
+	lwz	r6,CPU_SPEC_FEATURES(r4)
 	li	r7,CPU_FTR_CAN_NAP
 	andc	r6,r6,r7
-	stw	r6,CPU_SPEC_FEATURES(r5)
+	stw	r6,CPU_SPEC_FEATURES(r4)
 	blr
 
 /* 750fx specific
@@ -225,12 +225,12 @@ BEGIN_FTR_SECTION
 	andis.	r11,r11,L3CR_L3E@h
 	beq	1f
 END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
-	lwz	r6,CPU_SPEC_FEATURES(r5)
+	lwz	r6,CPU_SPEC_FEATURES(r4)
 	andi.	r0,r6,CPU_FTR_L3_DISABLE_NAP
 	beq	1f
 	li	r7,CPU_FTR_CAN_NAP
 	andc	r6,r6,r7
-	stw	r6,CPU_SPEC_FEATURES(r5)
+	stw	r6,CPU_SPEC_FEATURES(r4)
 1:
 	mfspr	r11,SPRN_HID0
 
author
#193 lore raw

PATCH 193/272 n_gsm: copy mtu over when configuring via ioctl interface

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Ken Mills <[email protected]>

commit 91f78f36694b8748fda855b1f9e3614b027a744f upstream.

This field is settable but did not get copied.

---
 drivers/tty/n_gsm.c |    1 +
 1 file changed, 1 insertion(+)
drivers/tty/n_gsm.c +1 -0
@@ -2375,6 +2375,7 @@ static int gsmld_config(struct tty_struc
 
 	gsm->initiator = c->initiator;
 	gsm->mru = c->mru;
+	gsm->mtu = c->mtu;
 	gsm->encoding = c->encapsulation;
 	gsm->adaption = c->adaption;
 	gsm->n2 = c->n2;
author
#194 lore raw

PATCH 194/272 firewire: core: fix unstable I/O with Canon camcorder

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Stefan Richter <[email protected]>

commit 6044565af458e7fa6e748bff437ecc49dea88d79 upstream.

Regression since commit 10389536742c, "firewire: core: check for 1394a compliant IRM, fix inaccessibility of Sony camcorder":

The camcorder Canon MV5i generates lots of bus resets when asynchronous requests are sent to it (e.g. Config ROM read requests or FCP Command write requests) if the camcorder is not root node. This causes drop- outs in videos or makes the camcorder entirely inaccessible.
https://bugzilla.redhat.com/show_bug.cgi?id=633260

Fix this by allowing any Canon device, even if it is a pre-1394a IRM like MV5i are, to remain root node (if it is at least Cycle Master capable). With the FireWire controller cards that I tested, MV5i always becomes root node when plugged in and left to its own devices.

Reported-by Ralf Lange
---
 drivers/firewire/core-card.c |   11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
drivers/firewire/core-card.c +9 -2
@@ -75,6 +75,8 @@ static size_t config_rom_length = 1 + 4
 #define BIB_IRMC		((1) << 31)
 #define NODE_CAPABILITIES	0x0c0083c0 /* per IEEE 1394 clause 8.3.2.6.5.2 */
 
+#define CANON_OUI		0x000085
+
 static void generate_config_rom(struct fw_card *card, __be32 *config_rom)
 {
 	struct fw_descriptor *desc;
@@ -284,6 +286,7 @@ static void bm_work(struct work_struct *
 	bool root_device_is_running;
 	bool root_device_is_cmc;
 	bool irm_is_1394_1995_only;
+	bool keep_this_irm;
 
 	spin_lock_irq(&card->lock);
 
@@ -305,6 +308,10 @@ static void bm_work(struct work_struct *
 	irm_is_1394_1995_only = irm_device && irm_device->config_rom &&
 			(irm_device->config_rom[2] & 0x000000f0) == 0;
 
+	/* Canon MV5i works unreliably if it is not root node. */
+	keep_this_irm = irm_device && irm_device->config_rom &&
+			irm_device->config_rom[3] >> 8 == CANON_OUI;
+
 	root_id  = root_node->node_id;
 	irm_id   = card->irm_node->node_id;
 	local_id = card->local_node->node_id;
@@ -333,7 +340,7 @@ static void bm_work(struct work_struct *
 			goto pick_me;
 		}
 
-		if (irm_is_1394_1995_only) {
+		if (irm_is_1394_1995_only && !keep_this_irm) {
 			new_root_id = local_id;
 			fw_notify("%s, making local node (%02x) root.\n",
 				  "IRM is not 1394a compliant", new_root_id);
@@ -382,7 +389,7 @@ static void bm_work(struct work_struct *
 
 		spin_lock_irq(&card->lock);
 
-		if (rcode != RCODE_COMPLETE) {
+		if (rcode != RCODE_COMPLETE && !keep_this_irm) {
 			/*
 			 * The lock request failed, maybe the IRM
 			 * isn't really IRM capable after all. Let's
author
#195 lore raw

PATCH 195/272 workqueue: relax lockdep annotation on flush_work()

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Tejun Heo <[email protected]>

commit e159489baa717dbae70f9903770a6a4990865887 upstream.

Currently, the lockdep annotation in flush_work() requires exclusive access on the workqueue the target work is queued on and triggers warning if a work is trying to flush another work on the same workqueue; however, this is no longer true as workqueues can now execute multiple works concurrently.

This patch adds lock_map_acquire_read() and make process_one_work() hold read access to the workqueue while executing a work and start_flush_work() check for write access if concurrnecy level is one or the workqueue has a rescuer (as only one execution resource - the rescuer - is guaranteed to be available under memory pressure), and read access if higher.

This better represents what's going on and removes spurious lockdep warnings which are triggered by fake dependency chain created through flush_work().

* Peter pointed out that flushing another work from a WQ_MEM_RECLAIM wq breaks forward progress guarantee under memory pressure. Condition check accordingly updated.

---
 include/linux/lockdep.h |    3 +++
 kernel/workqueue.c      |   14 ++++++++++++--
 2 files changed, 15 insertions(+), 2 deletions(-)
include/linux/lockdep.h +3 -0
@@ -522,12 +522,15 @@ static inline void print_irqtrace_events
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 # ifdef CONFIG_PROVE_LOCKING
 #  define lock_map_acquire(l)		lock_acquire(l, 0, 0, 0, 2, NULL, _THIS_IP_)
+#  define lock_map_acquire_read(l)	lock_acquire(l, 0, 0, 2, 2, NULL, _THIS_IP_)
 # else
 #  define lock_map_acquire(l)		lock_acquire(l, 0, 0, 0, 1, NULL, _THIS_IP_)
+#  define lock_map_acquire_read(l)	lock_acquire(l, 0, 0, 2, 1, NULL, _THIS_IP_)
 # endif
 # define lock_map_release(l)			lock_release(l, 1, _THIS_IP_)
 #else
 # define lock_map_acquire(l)			do { } while (0)
+# define lock_map_acquire_read(l)		do { } while (0)
 # define lock_map_release(l)			do { } while (0)
 #endif
 
kernel/workqueue.c +12 -2
@@ -1806,7 +1806,7 @@ __acquires(&gcwq->lock)
 	spin_unlock_irq(&gcwq->lock);
 
 	work_clear_pending(work);
-	lock_map_acquire(&cwq->wq->lockdep_map);
+	lock_map_acquire_read(&cwq->wq->lockdep_map);
 	lock_map_acquire(&lockdep_map);
 	trace_workqueue_execute_start(work);
 	f(work);
@@ -2350,8 +2350,18 @@ static bool start_flush_work(struct work
 	insert_wq_barrier(cwq, barr, work, worker);
 	spin_unlock_irq(&gcwq->lock);
 
-	lock_map_acquire(&cwq->wq->lockdep_map);
+	/*
+	 * If @max_active is 1 or rescuer is in use, flushing another work
+	 * item on the same workqueue may lead to deadlock.  Make sure the
+	 * flusher is not running on the same workqueue by verifying write
+	 * access.
+	 */
+	if (cwq->wq->saved_max_active == 1 || cwq->wq->flags & WQ_RESCUER)
+		lock_map_acquire(&cwq->wq->lockdep_map);
+	else
+		lock_map_acquire_read(&cwq->wq->lockdep_map);
 	lock_map_release(&cwq->wq->lockdep_map);
+
 	return true;
 already_gone:
 	spin_unlock_irq(&gcwq->lock);
author
#196 lore raw

PATCH 196/272 ARM: SMP: use more sane register allocation for __fixup_smp_on_up

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Russell King <[email protected]>

commit 0eb0511d176534674600a1986c3c766756288908 upstream.

Use r0,r3-r6 rather than r0,r3,r4,r6,r7, which makes it easier to understand which registers can be modified. Also document which registers hold values which must be preserved.

---
 arch/arm/kernel/head.S |   39 ++++++++++++++++++++++-----------------
 1 file changed, 22 insertions(+), 17 deletions(-)
arch/arm/kernel/head.S +22 -17
@@ -91,6 +91,11 @@ ENTRY(stext)
 	movs	r8, r5				@ invalid machine (r5=0)?
  THUMB( it	eq )		@ force fixup-able long branch encoding
 	beq	__error_a			@ yes, error 'a'
+
+	/*
+	 * r1 = machine no, r2 = atags,
+	 * r8 = machinfo, r9 = cpuid, r10 = procinfo
+	 */
 	bl	__vet_atags
 #ifdef CONFIG_SMP_ON_UP
 	bl	__fixup_smp
@@ -387,19 +392,19 @@ ENDPROC(__turn_mmu_on)
 
 #ifdef CONFIG_SMP_ON_UP
 __fixup_smp:
-	mov	r7, #0x00070000
-	orr	r6, r7, #0xff000000	@ mask 0xff070000
-	orr	r7, r7, #0x41000000	@ val 0x41070000
-	and	r0, r9, r6
-	teq	r0, r7			@ ARM CPU and ARMv6/v7?
+	mov	r4, #0x00070000
+	orr	r3, r4, #0xff000000	@ mask 0xff070000
+	orr	r4, r4, #0x41000000	@ val 0x41070000
+	and	r0, r9, r3
+	teq	r0, r4			@ ARM CPU and ARMv6/v7?
 	bne	__fixup_smp_on_up	@ no, assume UP
 
-	orr	r6, r6, #0x0000ff00
-	orr	r6, r6, #0x000000f0	@ mask 0xff07fff0
-	orr	r7, r7, #0x0000b000
-	orr	r7, r7, #0x00000020	@ val 0x4107b020
-	and	r0, r9, r6
-	teq	r0, r7			@ ARM 11MPCore?
+	orr	r3, r3, #0x0000ff00
+	orr	r3, r3, #0x000000f0	@ mask 0xff07fff0
+	orr	r4, r4, #0x0000b000
+	orr	r4, r4, #0x00000020	@ val 0x4107b020
+	and	r0, r9, r3
+	teq	r0, r4			@ ARM 11MPCore?
 	moveq	pc, lr			@ yes, assume SMP
 
 	mrc	p15, 0, r0, c0, c0, 5	@ read MPIDR
@@ -408,13 +413,13 @@ __fixup_smp:
 
 __fixup_smp_on_up:
 	adr	r0, 1f
-	ldmia	r0, {r3, r6, r7}
+	ldmia	r0, {r3 - r5}
 	sub	r3, r0, r3
-	add	r6, r6, r3
-	add	r7, r7, r3
-2:	cmp	r6, r7
-	ldmia	r6!, {r0, r4}
-	strlo	r4, [r0, r3]
+	add	r4, r4, r3
+	add	r5, r5, r3
+2:	cmp	r4, r5
+	ldmia	r4!, {r0, r6}
+	strlo	r6, [r0, r3]
 	blo	2b
 	mov	pc, lr
 ENDPROC(__fixup_smp)
author
#197 lore raw

PATCH 197/272 ARM: smp_on_up: allow non-ARM SMP processors

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Russell King <[email protected]>

commit e98ff0f55a0232b578c9aa7f1c245868277ac7bc upstream.

Allow non-ARM SMP processors to use the SMP_ON_UP feature. CPUs supporting SMP must have the new CPU ID format, so check for this first. Then check for ARM11MPCore, which fails the MPIDR check. Lastly check the MPIDR reports multiprocessing extensions and that the CPU is part of a multiprocessing system.

---
 arch/arm/kernel/head.S |   22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)
arch/arm/kernel/head.S +10 -12
@@ -392,24 +392,22 @@ ENDPROC(__turn_mmu_on)
 
 #ifdef CONFIG_SMP_ON_UP
 __fixup_smp:
-	mov	r4, #0x00070000
-	orr	r3, r4, #0xff000000	@ mask 0xff070000
-	orr	r4, r4, #0x41000000	@ val 0x41070000
-	and	r0, r9, r3
-	teq	r0, r4			@ ARM CPU and ARMv6/v7?
+	and	r3, r9, #0x000f0000	@ architecture version
+	teq	r3, #0x000f0000		@ CPU ID supported?
 	bne	__fixup_smp_on_up	@ no, assume UP
 
-	orr	r3, r3, #0x0000ff00
-	orr	r3, r3, #0x000000f0	@ mask 0xff07fff0
+	bic	r3, r9, #0x00ff0000
+	bic	r3, r3, #0x0000000f	@ mask 0xff00fff0
+	mov	r4, #0x41000000
 	orr	r4, r4, #0x0000b000
-	orr	r4, r4, #0x00000020	@ val 0x4107b020
-	and	r0, r9, r3
-	teq	r0, r4			@ ARM 11MPCore?
+	orr	r4, r4, #0x00000020	@ val 0x4100b020
+	teq	r3, r4			@ ARM 11MPCore?
 	moveq	pc, lr			@ yes, assume SMP
 
 	mrc	p15, 0, r0, c0, c0, 5	@ read MPIDR
-	tst	r0, #1 << 31
-	movne	pc, lr			@ bit 31 => SMP
+	and	r0, r0, #0xc0000000	@ multiprocessing extensions and
+	teq	r0, #0x80000000		@ not part of a uniprocessor system?
+	moveq	pc, lr			@ yes, assume SMP
 
 __fixup_smp_on_up:
 	adr	r0, 1f
author
#198 lore raw

PATCH 198/272 CIFS: Fix oplock break handling (try #2)

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Pavel Shilovsky <[email protected]>

commit 12fed00de963433128b5366a21a55808fab2f756 upstream.

When we get oplock break notification we should set the appropriate value of OplockLevel field in oplock break acknowledge according to the oplock level held by the client in this time. As we only can have level II oplock or no oplock in the case of oplock break, we should be aware only about clientCanCacheRead field in cifsInodeInfo structure.

Also fix bug connected with wrong interpretation of OplockLevel field during oplock break notification processing.

---
 fs/cifs/cifsproto.h |    2 +-
 fs/cifs/cifssmb.c   |    4 +++-
 fs/cifs/file.c      |   21 +++++++++++----------
 fs/cifs/misc.c      |    2 +-
 4 files changed, 16 insertions(+), 13 deletions(-)
fs/cifs/cifsproto.h +1 -1
@@ -347,7 +347,7 @@ extern int CIFSSMBLock(const int xid, st
 			const __u16 netfid, const __u64 len,
 			const __u64 offset, const __u32 numUnlock,
 			const __u32 numLock, const __u8 lockType,
-			const bool waitFlag);
+			const bool waitFlag, const __u8 oplock_level);
 extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
 			const __u16 smb_file_id, const int get_flag,
 			const __u64 len, struct file_lock *,
fs/cifs/cifssmb.c +3 -1
@@ -1666,7 +1666,8 @@ int
 CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
 	    const __u16 smb_file_id, const __u64 len,
 	    const __u64 offset, const __u32 numUnlock,
-	    const __u32 numLock, const __u8 lockType, const bool waitFlag)
+	    const __u32 numLock, const __u8 lockType,
+	    const bool waitFlag, const __u8 oplock_level)
 {
 	int rc = 0;
 	LOCK_REQ *pSMB = NULL;
@@ -1694,6 +1695,7 @@ CIFSSMBLock(const int xid, struct cifsTc
 	pSMB->NumberOfLocks = cpu_to_le16(numLock);
 	pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
 	pSMB->LockType = lockType;
+	pSMB->OplockLevel = oplock_level;
 	pSMB->AndXCommand = 0xFF;	/* none */
 	pSMB->Fid = smb_file_id; /* netfid stays le */
 
fs/cifs/file.c +11 -10
@@ -779,12 +779,12 @@ int cifs_lock(struct file *file, int cmd
 
 		/* BB we could chain these into one lock request BB */
 		rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start,
-				 0, 1, lockType, 0 /* wait flag */ );
+				 0, 1, lockType, 0 /* wait flag */, 0);
 		if (rc == 0) {
 			rc = CIFSSMBLock(xid, tcon, netfid, length,
 					 pfLock->fl_start, 1 /* numUnlock */ ,
 					 0 /* numLock */ , lockType,
-					 0 /* wait flag */ );
+					 0 /* wait flag */, 0);
 			pfLock->fl_type = F_UNLCK;
 			if (rc != 0)
 				cERROR(1, "Error unlocking previously locked "
@@ -801,13 +801,13 @@ int cifs_lock(struct file *file, int cmd
 				rc = CIFSSMBLock(xid, tcon, netfid, length,
 					pfLock->fl_start, 0, 1,
 					lockType | LOCKING_ANDX_SHARED_LOCK,
-					0 /* wait flag */);
+					0 /* wait flag */, 0);
 				if (rc == 0) {
 					rc = CIFSSMBLock(xid, tcon, netfid,
 						length, pfLock->fl_start, 1, 0,
 						lockType |
 						LOCKING_ANDX_SHARED_LOCK,
-						0 /* wait flag */);
+						0 /* wait flag */, 0);
 					pfLock->fl_type = F_RDLCK;
 					if (rc != 0)
 						cERROR(1, "Error unlocking "
@@ -850,8 +850,8 @@ int cifs_lock(struct file *file, int cmd
 
 		if (numLock) {
 			rc = CIFSSMBLock(xid, tcon, netfid, length,
-					pfLock->fl_start,
-					0, numLock, lockType, wait_flag);
+					 pfLock->fl_start, 0, numLock, lockType,
+					 wait_flag, 0);
 
 			if (rc == 0) {
 				/* For Windows locks we must store them. */
@@ -871,9 +871,9 @@ int cifs_lock(struct file *file, int cmd
 						(pfLock->fl_start + length) >=
 						(li->offset + li->length)) {
 					stored_rc = CIFSSMBLock(xid, tcon,
-							netfid,
-							li->length, li->offset,
-							1, 0, li->type, false);
+							netfid, li->length,
+							li->offset, 1, 0,
+							li->type, false, 0);
 					if (stored_rc)
 						rc = stored_rc;
 					else {
@@ -2245,7 +2245,8 @@ void cifs_oplock_break(struct work_struc
 	 */
 	if (!cfile->oplock_break_cancelled) {
 		rc = CIFSSMBLock(0, tlink_tcon(cfile->tlink), cfile->netfid, 0,
-				 0, 0, 0, LOCKING_ANDX_OPLOCK_RELEASE, false);
+				 0, 0, 0, LOCKING_ANDX_OPLOCK_RELEASE, false,
+				 cinode->clientCanCacheRead ? 1 : 0);
 		cFYI(1, "Oplock release rc = %d", rc);
 	}
 
fs/cifs/misc.c +1 -1
@@ -571,7 +571,7 @@ is_valid_oplock_break(struct smb_hdr *bu
 				pCifsInode = CIFS_I(netfile->dentry->d_inode);
 
 				cifs_set_oplock_level(pCifsInode,
-						      pSMB->OplockLevel);
+					pSMB->OplockLevel ? OPLOCK_READ : 0);
 				/*
 				 * cifs_oplock_break_put() can't be called
 				 * from here.  Get reference after queueing
author
#199 lore raw

PATCH 199/272 cifs: Fix regression during share-level security mounts (Repost)

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Shirish Pargaonkar <[email protected]>

commit 540b2e377797d8715469d408b887baa9310c5f3e upstream.

NTLM response length was changed to 16 bytes instead of 24 bytes that are sent in Tree Connection Request during share-level security share mounts. Revert it back to 24 bytes.

---
 fs/cifs/connect.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
fs/cifs/connect.c +2 -2
@@ -2999,7 +2999,7 @@ CIFSTCon(unsigned int xid, struct cifsSe
 		bcc_ptr++;              /* skip password */
 		/* already aligned so no need to do it below */
 	} else {
-		pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
+		pSMB->PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
 		/* BB FIXME add code to fail this if NTLMv2 or Kerberos
 		   specified as required (when that support is added to
 		   the vfs in the future) as only NTLM or the much
@@ -3017,7 +3017,7 @@ CIFSTCon(unsigned int xid, struct cifsSe
 #endif /* CIFS_WEAK_PW_HASH */
 		SMBNTencrypt(tcon->password, ses->server->cryptkey, bcc_ptr);
 
-		bcc_ptr += CIFS_SESS_KEY_SIZE;
+		bcc_ptr += CIFS_AUTH_RESP_SIZE;
 		if (ses->capabilities & CAP_UNICODE) {
 			/* must align unicode strings */
 			*bcc_ptr = 0; /* null byte password */
author
#200 lore raw

PATCH 200/272 parisc : Remove broken line wrapping handling pdc_iodc_print()

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Guy Martin <[email protected]>

commit fbea668498e93bb38ac9226c7af9120a25957375 upstream.

Remove the broken line wrapping handling in pdc_iodc_print(). It is broken in 3 ways :
- It doesn't keep track of the current screen position, it just assumes that the new buffer will be printed at the begining of the screen.
- It doesn't take in account that non printable characters won't increase the current position on the screen.
- And last but not least, it triggers a kernel panic if a backspace is the first char in the provided buffer :

 Backtrace:
  [<0000000040128ec4>] pdc_console_write+0x44/0x78
  [<0000000040128f18>] pdc_console_tty_write+0x20/0x38
  [<000000004032f1ac>] n_tty_write+0x2a4/0x550
  [<000000004032b158>] tty_write+0x1e0/0x2d8
  [<00000000401bb420>] vfs_write+0xb8/0x188
  [<00000000401bb630>] sys_write+0x68/0xb8
  [<0000000040104eb8>] syscall_exit+0x0/0x14

Most terminals handle the line wrapping just fine. I've confirmed that it works correctly on a C8000 with both vga and serial output.

---
 arch/parisc/kernel/firmware.c |   13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)
arch/parisc/kernel/firmware.c +1 -12
@@ -1126,15 +1126,13 @@ int pdc_iodc_print(const unsigned char *
 	unsigned int i;
 	unsigned long flags;
 
-	for (i = 0; i < count && i < 79;) {
+	for (i = 0; i < count;) {
 		switch(str[i]) {
 		case '\n':
 			iodc_dbuf[i+0] = '\r';
 			iodc_dbuf[i+1] = '\n';
 			i += 2;
 			goto print;
-		case '\b':	/* BS */
-			i--; /* overwrite last */
 		default:
 			iodc_dbuf[i] = str[i];
 			i++;
@@ -1142,15 +1140,6 @@ int pdc_iodc_print(const unsigned char *
 		}
 	}
 
-	/* if we're at the end of line, and not already inserting a newline,
-	 * insert one anyway. iodc console doesn't claim to support >79 char
-	 * lines. don't account for this in the return value.
-	 */
-	if (i == 79 && iodc_dbuf[i-1] != '\n') {
-		iodc_dbuf[i+0] = '\r';
-		iodc_dbuf[i+1] = '\n';
-	}
-
 print:
         spin_lock_irqsave(&pdc_lock, flags);
         real32_call(PAGE0->mem_cons.iodc_io,
author
#201 lore raw

PATCH 201/272 watchdog: Fix sysctl consistency

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Marcin Slusarz <[email protected]>

commit 397357666de6b5b6adb5fa99f9758ec8cf30ac34 upstream.

If it was not possible to enable watchdog for any cpu, switch watchdog_enabled back to 0, because it's visible via kernel.watchdog sysctl.

Cc Peter Zijlstra <[email protected]>
Cc Frederic Weisbecker <[email protected]>

LKML-Reference: <[email protected]>

---
 kernel/watchdog.c |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
kernel/watchdog.c +7 -6
@@ -430,9 +430,6 @@ static int watchdog_enable(int cpu)
 		wake_up_process(p);
 	}
 
-	/* if any cpu succeeds, watchdog is considered enabled for the system */
-	watchdog_enabled = 1;
-
 	return 0;
 }
 
@@ -460,12 +457,16 @@ static void watchdog_disable(int cpu)
 static void watchdog_enable_all_cpus(void)
 {
 	int cpu;
-	int result = 0;
+
+	watchdog_enabled = 0;
 
 	for_each_online_cpu(cpu)
-		result += watchdog_enable(cpu);
+		if (!watchdog_enable(cpu))
+			/* if any cpu succeeds, watchdog is considered
+			   enabled for the system */
+			watchdog_enabled = 1;
 
-	if (result)
+	if (!watchdog_enabled)
 		printk(KERN_ERR "watchdog: failed to be enabled on some cpus\n");
 
 }
author
#202 lore raw

PATCH 202/272 watchdog: Dont change watchdog state on read of sysctl

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Marcin Slusarz <[email protected]>

commit 9ffdc6c37df131f89d52001e0ef03091b158826f upstream.

[ add {}'s to fix a warning ]
Cc Peter Zijlstra <[email protected]>
Cc Frederic Weisbecker <[email protected]>

LKML-Reference: <[email protected]>

---
 kernel/watchdog.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
kernel/watchdog.c +6 -4
@@ -497,10 +497,12 @@ int proc_dowatchdog_enabled(struct ctl_t
 {
 	proc_dointvec(table, write, buffer, length, ppos);
 
-	if (watchdog_enabled)
-		watchdog_enable_all_cpus();
-	else
-		watchdog_disable_all_cpus();
+	if (write) {
+		if (watchdog_enabled)
+			watchdog_enable_all_cpus();
+		else
+			watchdog_disable_all_cpus();
+	}
 	return 0;
 }
 
author
#203 lore raw

PATCH 203/272 memsw: handle swapaccount kernel parameter correctly

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Michal Hocko <[email protected]>

commit fceda1bf498677501befc7da72fd2e4de7f18466 upstream.

__setup based kernel command line parameters handlers which are handled in obsolete_checksetup are provided with the parameter value including = (more precisely everything right after the parameter name).

This means that the current implementation of swapaccount[=1|0] doesn't work at all because if there is a value for the parameter then we are testing for "0" resp. "1" but we are getting "=0" resp. "=1" and if there is no parameter value we are getting an empty string rather than NULL.

The original noswapccount parameter, which doesn't care about the value, works correctly.

---
 mm/memcontrol.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
mm/memcontrol.c +3 -3
@@ -4930,9 +4930,9 @@ struct cgroup_subsys mem_cgroup_subsys =
 static int __init enable_swap_account(char *s)
 {
 	/* consider enabled if no parameter or 1 is given */
-	if (!s || !strcmp(s, "1"))
+	if (!(*s) || !strcmp(s, "=1"))
 		really_do_swap_account = 1;
-	else if (!strcmp(s, "0"))
+	else if (!strcmp(s, "=0"))
 		really_do_swap_account = 0;
 	return 1;
 }
@@ -4940,7 +4940,7 @@ __setup("swapaccount", enable_swap_accou
 
 static int __init disable_swap_account(char *s)
 {
-	enable_swap_account("0");
+	enable_swap_account("=0");
 	return 1;
 }
 __setup("noswapaccount", disable_swap_account);
author
#204 lore raw

PATCH 204/272 perf: Fix alloc_callchain_buffers()

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Eric Dumazet <[email protected]>

commit 88d4f0db7fa8785859c1d637f9aac210932b6216 upstream.

Commit 927c7a9e92c4 ("perf: Fix race in callchains") introduced a mismatch in the sizing of struct callchain_cpus_entries.

nr_cpu_ids must be used instead of num_possible_cpus(), or we might get out of bound memory accesses on some machines.

Cc Frederic Weisbecker <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Arnaldo Carvalho de Melo <[email protected]>
Cc David Miller <[email protected]>
Cc Stephane Eranian <[email protected]>

LKML-Reference: <1295980851.3588.351.camel@edumazet-laptop>

---
 kernel/perf_event.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
kernel/perf_event.c +1 -2
@@ -1872,8 +1872,7 @@ static int alloc_callchain_buffers(void)
 	 * accessed from NMI. Use a temporary manual per cpu allocation
 	 * until that gets sorted out.
 	 */
-	size = sizeof(*entries) + sizeof(struct perf_callchain_entry *) *
-		num_possible_cpus();
+	size = offsetof(struct callchain_cpus_entries, cpu_entries[nr_cpu_ids]);
 
 	entries = kzalloc(size, GFP_KERNEL);
 	if (!entries)
author
#205 lore raw

PATCH 205/272 perf: Find_get_context: fix the per-cpu-counter check

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Oleg Nesterov <[email protected]>

commit 22a4ec729017ba613337a28f306f94ba5023fe2e upstream.

If task == NULL, find_get_context() should always check that cpu is correct.

Afaics, the bug was introduced by 38a81da2 "perf events: Clean up pid passing", but even before that commit "&& cpu != -1" was not exactly right, -ESRCH from find_task_by_vpid() is not accurate.

Cc Alan Stern <[email protected]>
Cc Arnaldo Carvalho de Melo <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Prasad <[email protected]>
Cc Roland McGrath <[email protected]>

LKML-Reference: <[email protected]>

---
 kernel/perf_event.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/perf_event.c +1 -1
@@ -2100,7 +2100,7 @@ find_get_context(struct pmu *pmu, struct
 	unsigned long flags;
 	int ctxn, err;
 
-	if (!task && cpu != -1) {
+	if (!task) {
 		/* Must be root to operate on a CPU event: */
 		if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
 			return ERR_PTR(-EACCES);
author
#206 lore raw

PATCH 206/272 perf: Validate cpu early in perf_event_alloc()

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Oleg Nesterov <[email protected]>

commit 66832eb4baaaa9abe4c993ddf9113a79e39b9915 upstream.

Starting from perf_event_alloc()->perf_init_event(), the kernel assumes that event->cpu is either -1 or the valid CPU number.

Change perf_event_alloc() to validate this argument early. This also means we can remove the similar check in find_get_context().

Cc Alan Stern <[email protected]>
Cc Arnaldo Carvalho de Melo <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Prasad <[email protected]>
Cc Roland McGrath <[email protected]>

LKML-Reference: <[email protected]>

---
 kernel/perf_event.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
kernel/perf_event.c +6 -4
@@ -2105,9 +2105,6 @@ find_get_context(struct pmu *pmu, struct
 		if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
 			return ERR_PTR(-EACCES);
 
-		if (cpu < 0 || cpu >= nr_cpumask_bits)
-			return ERR_PTR(-EINVAL);
-
 		/*
 		 * We could be clever and allow to attach a event to an
 		 * offline CPU and activate it when the CPU comes up, but
@@ -5304,6 +5301,11 @@ perf_event_alloc(struct perf_event_attr
 	struct hw_perf_event *hwc;
 	long err;
 
+	if ((unsigned)cpu >= nr_cpu_ids) {
+		if (!task || cpu != -1)
+			return ERR_PTR(-EINVAL);
+	}
+
 	event = kzalloc(sizeof(*event), GFP_KERNEL);
 	if (!event)
 		return ERR_PTR(-ENOMEM);
@@ -5352,7 +5354,7 @@ perf_event_alloc(struct perf_event_attr
 
 	if (!overflow_handler && parent_event)
 		overflow_handler = parent_event->overflow_handler;
-	
+
 	event->overflow_handler	= overflow_handler;
 
 	if (attr->disabled)
author
#207 lore raw

PATCH 207/272 char/ipmi: fix OOPS caused by pnp_unregister_driver on unregistered driver

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Corey Minyard <[email protected]>

commit d2478521afc20227658a10a8c5c2bf1a2aa615b3 upstream.

This patch fixes an OOPS triggered when calling modprobe ipmi_si a second time after the first modprobe returned without finding any ipmi devices. This can happen if you reload the module after having the first module load fail. The driver was not deregistering from PNP in that case.

Peter Huewe originally reported this patch and supplied a fix, I have a different patch based on Linus' suggestion that cleans things up a bit more.

---
 drivers/char/ipmi/ipmi_si_intf.c |   12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)
drivers/char/ipmi/ipmi_si_intf.c +2 -10
@@ -320,6 +320,7 @@ static int unload_when_empty = 1;
 static int add_smi(struct smi_info *smi);
 static int try_smi_init(struct smi_info *smi);
 static void cleanup_one_si(struct smi_info *to_clean);
+static void cleanup_ipmi_si(void);
 
 static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list);
 static int register_xaction_notifier(struct notifier_block *nb)
@@ -3435,16 +3436,7 @@ static int __devinit init_ipmi_si(void)
 	mutex_lock(&smi_infos_lock);
 	if (unload_when_empty && list_empty(&smi_infos)) {
 		mutex_unlock(&smi_infos_lock);
-#ifdef CONFIG_PCI
-		if (pci_registered)
-			pci_unregister_driver(&ipmi_pci_driver);
-#endif
-
-#ifdef CONFIG_PPC_OF
-		if (of_registered)
-			of_unregister_platform_driver(&ipmi_of_platform_driver);
-#endif
-		driver_unregister(&ipmi_driver.driver);
+		cleanup_ipmi_si();
 		printk(KERN_WARNING PFX
 		       "Unable to find any System Interface(s)\n");
 		return -ENODEV;
author
#208 lore raw

PATCH 208/272 ssb-pcmcia: Fix parsing of invariants tuples

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: =?UTF-8?q?Michael=20B=C3=BCsch?= <[email protected]>

commit dd3cb633078fb12e06ce6cebbdfbf55a7562e929 upstream.

This fixes parsing of the device invariants (MAC address) for PCMCIA SSB devices.

ssb_pcmcia_do_get_invariants expects an iv pointer as data argument.

---
 drivers/ssb/pcmcia.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ssb/pcmcia.c +1 -1
@@ -733,7 +733,7 @@ int ssb_pcmcia_get_invariants(struct ssb
 
 	/* Fetch the vendor specific tuples. */
 	res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS,
-				ssb_pcmcia_do_get_invariants, sprom);
+				ssb_pcmcia_do_get_invariants, iv);
 	if ((res == 0) || (res == -ENOSPC))
 		return 0;
 
author
#209 lore raw

PATCH 209/272 nbd: remove module-level ioctl mutex

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Soren Hansen <[email protected]>

commit de1f016f882e52facc3c8609599f827bcdd14af9 upstream.

Commit 2a48fc0ab242417 ("block: autoconvert trivial BKL users to private mutex") replaced uses of the BKL in the nbd driver with mutex operations. Since then, I've been been seeing these lock ups:

 INFO: task qemu-nbd:16115 blocked for more than 120 seconds.
 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
 qemu-nbd      D 0000000000000001     0 16115  16114 0x00000004
  ffff88007d775d98 0000000000000082 ffff88007d775fd8 ffff88007d774000
  0000000000013a80 ffff8800020347e0 ffff88007d775fd8 0000000000013a80
  ffff880133730000 ffff880002034440 ffffea0004333db8 ffffffffa071c020
 Call Trace:
  [<ffffffff815b9997>] __mutex_lock_slowpath+0xf7/0x180
  [<ffffffff815b93eb>] mutex_lock+0x2b/0x50
  [<ffffffffa071a21c>] nbd_ioctl+0x6c/0x1c0 [nbd]
  [<ffffffff812cb970>] blkdev_ioctl+0x230/0x730
  [<ffffffff811967a1>] block_ioctl+0x41/0x50
  [<ffffffff81175c03>] do_vfs_ioctl+0x93/0x370
  [<ffffffff81175f61>] sys_ioctl+0x81/0xa0
  [<ffffffff8100c0c2>] system_call_fastpath+0x16/0x1b

Instrumenting the nbd module's ioctl handler with some extra logging clearly shows the NBD_DO_IT ioctl being invoked which is a long-lived ioctl in the sense that it doesn't return until another ioctl asks the driver to disconnect. However, that other ioctl blocks, waiting for the module-level mutex that replaced the BKL, and then we're stuck.

This patch removes the module-level mutex altogether. It's clearly wrong, and as far as I can see, it's entirely unnecessary, since the nbd driver maintains per-device mutexes, and I don't see anything that would require a module-level (or kernel-level, for that matter) mutex.

---
 drivers/block/nbd.c |    3 ---
 1 file changed, 3 deletions(-)
drivers/block/nbd.c +0 -3
@@ -53,7 +53,6 @@
 #define DBG_BLKDEV      0x0100
 #define DBG_RX          0x0200
 #define DBG_TX          0x0400
-static DEFINE_MUTEX(nbd_mutex);
 static unsigned int debugflags;
 #endif /* NDEBUG */
 
@@ -718,11 +717,9 @@ static int nbd_ioctl(struct block_device
 	dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n",
 			lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg);
 
-	mutex_lock(&nbd_mutex);
 	mutex_lock(&lo->tx_lock);
 	error = __nbd_ioctl(bdev, lo, cmd, arg);
 	mutex_unlock(&lo->tx_lock);
-	mutex_unlock(&nbd_mutex);
 
 	return error;
 }
author
#210 lore raw

PATCH 210/272 memory hotplug: one more lock on memory hotplug

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: KAMEZAWA Hiroyuki <[email protected]>

commit 925268a06dc2b1ff7bfcc37419a6827a0e739639 upstream.

Now, memory_hotplug_(un)lock() is used for add/remove/offline pages for avoiding races with hibernation. But this should be held in online_pages(), too. It seems asymmetric.

There are cases where one has to avoid a race with memory hotplug notifier and his own local code, and hotplug v.s. hotplug. This will add a generic solution for avoiding races. In other view, having lock here has no big impacts. online pages is tend to be done by udev script at el against each memory section one by one.

Then, it's better to have lock here, too.

---
 include/linux/memory_hotplug.h |    6 ++++++
 mm/memory_hotplug.c            |    4 ++++
 2 files changed, 10 insertions(+)
include/linux/memory_hotplug.h +6 -0
@@ -161,6 +161,12 @@ extern void register_page_bootmem_info_n
 extern void put_page_bootmem(struct page *page);
 #endif
 
+/*
+ * Lock for memory hotplug guarantees 1) all callbacks for memory hotplug
+ * notifier will be called under this. 2) offline/online/add/remove memory
+ * will not run simultaneously.
+ */
+
 void lock_memory_hotplug(void);
 void unlock_memory_hotplug(void);
 
mm/memory_hotplug.c +4 -0
@@ -407,6 +407,7 @@ int online_pages(unsigned long pfn, unsi
 	int ret;
 	struct memory_notify arg;
 
+	lock_memory_hotplug();
 	arg.start_pfn = pfn;
 	arg.nr_pages = nr_pages;
 	arg.status_change_nid = -1;
@@ -419,6 +420,7 @@ int online_pages(unsigned long pfn, unsi
 	ret = notifier_to_errno(ret);
 	if (ret) {
 		memory_notify(MEM_CANCEL_ONLINE, &arg);
+		unlock_memory_hotplug();
 		return ret;
 	}
 	/*
@@ -443,6 +445,7 @@ int online_pages(unsigned long pfn, unsi
 		printk(KERN_DEBUG "online_pages %lx at %lx failed\n",
 			nr_pages, pfn);
 		memory_notify(MEM_CANCEL_ONLINE, &arg);
+		unlock_memory_hotplug();
 		return ret;
 	}
 
@@ -467,6 +470,7 @@ int online_pages(unsigned long pfn, unsi
 
 	if (onlined_pages)
 		memory_notify(MEM_ONLINE, &arg);
+	unlock_memory_hotplug();
 
 	return 0;
 }
author
#211 lore raw

PATCH 211/272 backlight: fix 88pm860x_bl macro collision

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Randy Dunlap <[email protected]>

commit 2550326ac7a062fdfc204f9a3b98bdb9179638fc upstream.

Fix collision with kernel-supplied #define:

drivers/video/backlight/88pm860x_bl.c:24:1: warning: "CURRENT_MASK" redefined arch/x86/include/asm/page_64_types.h:6:1: warning: this is the location of the previous definition

---
 drivers/video/backlight/88pm860x_bl.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/video/backlight/88pm860x_bl.c +2 -2
@@ -21,7 +21,7 @@
 #define MAX_BRIGHTNESS		(0xFF)
 #define MIN_BRIGHTNESS		(0)
 
-#define CURRENT_MASK		(0x1F << 1)
+#define CURRENT_BITMASK		(0x1F << 1)
 
 struct pm860x_backlight_data {
 	struct pm860x_chip *chip;
@@ -85,7 +85,7 @@ static int pm860x_backlight_set(struct b
 	if ((data->current_brightness == 0) && brightness) {
 		if (data->iset) {
 			ret = pm860x_set_bits(data->i2c, wled_idc(data->port),
-					      CURRENT_MASK, data->iset);
+					      CURRENT_BITMASK, data->iset);
 			if (ret < 0)
 				goto out;
 		}
author
#212 lore raw

PATCH 212/272 fs/direct-io.c: dont try to allocate more than BIO_MAX_PAGES in a bio

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: David Dillow <[email protected]>

commit 20d9600cb407b0b55fef6ee814b60345c6f58264 upstream.

When using devices that support max_segments > BIO_MAX_PAGES (256), direct IO tries to allocate a bio with more pages than allowed, which leads to an oops in dio_bio_alloc(). Clamp the request to the supported maximum, and change dio_bio_alloc() to reflect that bio_alloc() will always return a bio when called with __GFP_WAIT and a valid number of vectors.

---
 fs/direct-io.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
fs/direct-io.c +7 -3
@@ -325,12 +325,16 @@ void dio_end_io(struct bio *bio, int err
 }
 EXPORT_SYMBOL_GPL(dio_end_io);
 
-static int
+static void
 dio_bio_alloc(struct dio *dio, struct block_device *bdev,
 		sector_t first_sector, int nr_vecs)
 {
 	struct bio *bio;
 
+	/*
+	 * bio_alloc() is guaranteed to return a bio when called with
+	 * __GFP_WAIT and we request a valid number of vectors.
+	 */
 	bio = bio_alloc(GFP_KERNEL, nr_vecs);
 
 	bio->bi_bdev = bdev;
@@ -342,7 +346,6 @@ dio_bio_alloc(struct dio *dio, struct bl
 
 	dio->bio = bio;
 	dio->logical_offset_in_bio = dio->cur_page_fs_offset;
-	return 0;
 }
 
 /*
@@ -583,8 +586,9 @@ static int dio_new_bio(struct dio *dio,
 		goto out;
 	sector = start_sector << (dio->blkbits - 9);
 	nr_pages = min(dio->pages_in_io, bio_get_nr_vecs(dio->map_bh.b_bdev));
+	nr_pages = min(nr_pages, BIO_MAX_PAGES);
 	BUG_ON(nr_pages <= 0);
-	ret = dio_bio_alloc(dio, dio->map_bh.b_bdev, sector, nr_pages);
+	dio_bio_alloc(dio, dio->map_bh.b_bdev, sector, nr_pages);
 	dio->boundary = 0;
 out:
 	return ret;
author
#213 lore raw

PATCH 213/272 kernel/smp.c: fix smp_call_function_many() SMP race

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Anton Blanchard <[email protected]>

commit 6dc19899958e420a931274b94019e267e2396d3e upstream.

I noticed a failure where we hit the following WARN_ON in generic_smp_call_function_interrupt:

                if (!cpumask_test_and_clear_cpu(cpu, data->cpumask))
                        continue;

                data->csd.func(data->csd.info);

                refs = atomic_dec_return(&data->refs);
                WARN_ON(refs < 0);      <-------------------------

We atomically tested and cleared our bit in the cpumask, and yet the number of cpus left (ie refs) was 0. How can this be?

It turns out commit 54fdade1c3332391948ec43530c02c4794a38172 ("generic-ipi: make struct call_function_data lockless") is at fault. It removes locking from smp_call_function_many and in doing so creates a rather complicated race.

The problem comes about because:

- The smp_call_function_many interrupt handler walks call_function.queue without any locking.
- We reuse a percpu data structure in smp_call_function_many.
- We do not wait for any RCU grace period before starting the next smp_call_function_many.

Imagine a scenario where CPU A does two smp_call_functions back to back, and CPU B does an smp_call_function in between. We concentrate on how CPU C handles the calls:

CPU A CPU B CPU C CPU D

smp_call_function
smp_call_function_interrupt
walks
call_function.queue sees data from CPU A on list

smp_call_function

smp_call_function_interrupt
walks

call_function.queue sees
(stale) CPU A on list
smp_call_function int clears last ref on A list_del_rcu, unlock
smp_call_function reuses
percpu *data A
data->cpumask sees and clears bit in cpumask might be using old or new fn! decrements refs below 0

set data->refs (too late!)

The important thing to note is since the interrupt handler walks a potentially stale call_function.queue without any locking, then another cpu can view the percpu *data structure at any time, even when the owner is in the process of initialising it.

The following test case hits the WARN_ON 100% of the time on my PowerPC box (having 128 threads does help :)

#include <linux/module.h>
#include <linux/init.h>

#define ITERATIONS 100

static void do_nothing_ipi(void *dummy)
{
}

static void do_ipis(struct work_struct *dummy)

{
	int i;

	for (i = 0; i < ITERATIONS; i++)
		smp_call_function(do_nothing_ipi, NULL, 1);

	printk(KERN_DEBUG "cpu %d finished\n", smp_processor_id());
}

static struct work_struct work[NR_CPUS];

static int __init testcase_init(void)

{
	int cpu;

	for_each_online_cpu(cpu) {
		INIT_WORK(&work[cpu], do_ipis);
		schedule_work_on(cpu, &work[cpu]);
	}

	return 0;
}

static void __exit testcase_exit(void)
{
}

module_init(testcase_init)
module_exit(testcase_exit)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Anton Blanchard");

I tried to fix it by ordering the read and the write of ->cpumask and ->refs. In doing so I missed a critical case but Paul McKenney was able to spot my bug thankfully :) To ensure we arent viewing previous iterations the interrupt handler needs to read ->refs then ->cpumask then ->refs _again_.

Thanks to Milton Miller and Paul McKenney for helping to debug this issue.

[[email protected]: add WARN_ON and BUG_ON, remove extra read of refs before initial read of mask that doesn't help (also noted by Peter Zijlstra), adjust comments, hopefully clarify scenario ]
[[email protected]: remove excess tests]
Cc Ingo Molnar <[email protected]>
Cc "Paul E. McKenney" <[email protected]>
---
 kernel/smp.c |   30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
kernel/smp.c +30 -0
@@ -194,6 +194,24 @@ void generic_smp_call_function_interrupt
 	list_for_each_entry_rcu(data, &call_function.queue, csd.list) {
 		int refs;
 
+		/*
+		 * Since we walk the list without any locks, we might
+		 * see an entry that was completed, removed from the
+		 * list and is in the process of being reused.
+		 *
+		 * We must check that the cpu is in the cpumask before
+		 * checking the refs, and both must be set before
+		 * executing the callback on this cpu.
+		 */
+
+		if (!cpumask_test_cpu(cpu, data->cpumask))
+			continue;
+
+		smp_rmb();
+
+		if (atomic_read(&data->refs) == 0)
+			continue;
+
 		if (!cpumask_test_and_clear_cpu(cpu, data->cpumask))
 			continue;
 
@@ -202,6 +220,8 @@ void generic_smp_call_function_interrupt
 		refs = atomic_dec_return(&data->refs);
 		WARN_ON(refs < 0);
 		if (!refs) {
+			WARN_ON(!cpumask_empty(data->cpumask));
+
 			raw_spin_lock(&call_function.lock);
 			list_del_rcu(&data->csd.list);
 			raw_spin_unlock(&call_function.lock);
@@ -453,11 +473,21 @@ void smp_call_function_many(const struct
 
 	data = &__get_cpu_var(cfd_data);
 	csd_lock(&data->csd);
+	BUG_ON(atomic_read(&data->refs) || !cpumask_empty(data->cpumask));
 
 	data->csd.func = func;
 	data->csd.info = info;
 	cpumask_and(data->cpumask, mask, cpu_online_mask);
 	cpumask_clear_cpu(this_cpu, data->cpumask);
+
+	/*
+	 * To ensure the interrupt handler gets an complete view
+	 * we order the cpumask and refs writes and order the read
+	 * of them in the interrupt handler.  In addition we may
+	 * only clear our own cpu bit from the mask.
+	 */
+	smp_wmb();
+
 	atomic_set(&data->refs, cpumask_weight(data->cpumask));
 
 	raw_spin_lock_irqsave(&call_function.lock, flags);
author
#214 lore raw

PATCH 214/272 hostap_cs: fix sleeping function called from invalid context

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Stanislaw Gruszka <[email protected]>

commit 4e5518ca53be29c1ec3c00089c97bef36bfed515 upstream.

pcmcia_request_irq() and pcmcia_enable_device() are intended to be called from process context (first function allocate memory with GFP_KERNEL, second take a mutex). We can not take spin lock and call them.

It's safe to move spin lock after pcmcia_enable_device() as we still hold off IRQ until dev->base_addr is 0 and driver will not proceed with interrupts when is not ready.

Patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=643758

---
 drivers/net/wireless/hostap/hostap_cs.c |   15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)
drivers/net/wireless/hostap/hostap_cs.c +6 -9
@@ -518,22 +518,21 @@ static int prism2_config(struct pcmcia_d
 	hw_priv->link = link;
 
 	/*
-	 * Make sure the IRQ handler cannot proceed until at least
-	 * dev->base_addr is initialized.
+	 * We enable IRQ here, but IRQ handler will not proceed
+	 * until dev->base_addr is set below. This protect us from
+	 * receive interrupts when driver is not initialized.
 	 */
-	spin_lock_irqsave(&local->irq_init_lock, flags);
-
 	ret = pcmcia_request_irq(link, prism2_interrupt);
 	if (ret)
-		goto failed_unlock;
+		goto failed;
 
 	ret = pcmcia_enable_device(link);
 	if (ret)
-		goto failed_unlock;
+		goto failed;
 
+	spin_lock_irqsave(&local->irq_init_lock, flags);
 	dev->irq = link->irq;
 	dev->base_addr = link->resource[0]->start;
-
 	spin_unlock_irqrestore(&local->irq_init_lock, flags);
 
 	local->shutdown = 0;
@@ -546,8 +545,6 @@ static int prism2_config(struct pcmcia_d
 
 	return ret;
 
- failed_unlock:
-	spin_unlock_irqrestore(&local->irq_init_lock, flags);
  failed:
 	kfree(hw_priv);
 	prism2_release((u_long)link);
author
#215 lore raw

PATCH 215/272 md: fix regression with re-adding devices to arrays with no metadata

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: NeilBrown <[email protected]>

commit bf572541ab44240163eaa2d486b06f306a31d45a upstream.

Commit 1a855a0606 (2.6.37-rc4) fixed a problem where devices were re-added when they shouldn't be but caused a regression in a less common case that means sometimes devices cannot be re-added when they should be.

In particular, when re-adding a device to an array without metadata we should always access the device, but after the above commit we didn't.

This patch sets the In_sync flag in that case so that the re-add succeeds.

This patch is suitable for any -stable kernel to which 1a855a0606 was applied.

---
 drivers/md/md.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/md/md.c +3 -2
@@ -5159,9 +5159,10 @@ static int add_new_disk(mddev_t * mddev,
 		/* set saved_raid_disk if appropriate */
 		if (!mddev->persistent) {
 			if (info->state & (1<<MD_DISK_SYNC)  &&
-			    info->raid_disk < mddev->raid_disks)
+			    info->raid_disk < mddev->raid_disks) {
 				rdev->raid_disk = info->raid_disk;
-			else
+				set_bit(In_sync, &rdev->flags);
+			} else
 				rdev->raid_disk = -1;
 		} else
 			super_types[mddev->major_version].
author
#216 lore raw

PATCH 216/272 md: fix regression resulting in delays in clearing bits in a bitmap

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: NeilBrown <[email protected]>

commit 6c9879101442b08581e8a0e3ae6b7f643a78fd63 upstream.

commit 589a594be1fb (2.6.37-rc4) fixed a problem were md_thread would sometimes call the ->run function at a bad time.

If an error is detected during array start up after the md_thread has been started, the md_thread is killed. This resulted in the ->run function being called once. However the array may not be in a state that it is safe to call ->run.

However the fix imposed meant that ->run was not called on a timeout. This means that when an array goes idle, bitmap bits do not get cleared promptly. While the array is busy the bits will still be cleared when appropriate so this is not very serious. There is no risk to data.

Change the test so that we only avoid calling ->run when the thread is being stopped. This more explicitly addresses the problem situation.

This is suitable for 2.6.37-stable and any -stable kernel to which 589a594be1fb was applied.

---
 drivers/md/md.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/md/md.c +2 -1
@@ -6042,7 +6042,8 @@ static int md_thread(void * arg)
 			 || kthread_should_stop(),
 			 thread->timeout);
 
-		if (test_and_clear_bit(THREAD_WAKEUP, &thread->flags))
+		clear_bit(THREAD_WAKEUP, &thread->flags);
+		if (!kthread_should_stop())
 			thread->run(thread->mddev);
 	}
 
author
#217 lore raw

PATCH 217/272 md: Ensure no IO request to get md device before it is properly initialised.

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: NeilBrown <[email protected]>

commit 0ca69886a8273ac1350143d562280bfcbe4760dc upstream.

When an md device is in the process of coming on line it is possible for an IO request (typically a partition table probe) to get through before the array is fully initialised, which can cause unexpected behaviour (e.g. a crash).

So explicitly record when the array is ready for IO and don't allow IO through until then.

There is no possibility for a similar problem when the array is going off-line as there must only be one 'open' at that time, and it is busy off-lining the array and so cannot send IO requests. So no memory barrier is needed in md_stop()

This has been a bug since commit 409c57f3801 in 2.6.30 which introduced md_make_request. Before then, each personality would register its own make_request_fn when it was ready. This is suitable for any stable kernel from 2.6.30.y onwards.

---
 drivers/md/md.c |    8 ++++++--
 drivers/md/md.h |    3 ++-
 2 files changed, 8 insertions(+), 3 deletions(-)
drivers/md/md.c +6 -2
@@ -288,10 +288,12 @@ static int md_make_request(struct reques
 	int rv;
 	int cpu;
 
-	if (mddev == NULL || mddev->pers == NULL) {
+	if (mddev == NULL || mddev->pers == NULL
+	    || !mddev->ready) {
 		bio_io_error(bio);
 		return 0;
 	}
+	smp_rmb(); /* Ensure implications of  'active' are visible */
 	rcu_read_lock();
 	if (mddev->suspended) {
 		DEFINE_WAIT(__wait);
@@ -4564,7 +4566,8 @@ int md_run(mddev_t *mddev)
 	mddev->safemode_timer.data = (unsigned long) mddev;
 	mddev->safemode_delay = (200 * HZ)/1000 +1; /* 200 msec delay */
 	mddev->in_sync = 1;
-
+	smp_wmb();
+	mddev->ready = 1;
 	list_for_each_entry(rdev, &mddev->disks, same_set)
 		if (rdev->raid_disk >= 0) {
 			char nm[20];
@@ -4725,6 +4728,7 @@ EXPORT_SYMBOL_GPL(md_stop_writes);
 
 void md_stop(mddev_t *mddev)
 {
+	mddev->ready = 0;
 	mddev->pers->stop(mddev);
 	if (mddev->pers->sync_request && mddev->to_remove == NULL)
 		mddev->to_remove = &md_redundancy_group;
drivers/md/md.h +2 -1
@@ -148,7 +148,8 @@ struct mddev_s
 						       * are happening, so run/
 						       * takeover/stop are not safe
 						       */
-
+	int				ready; /* See when safe to pass
+						* IO requests down */
 	struct gendisk			*gendisk;
 
 	struct kobject			kobj;
author
#218 lore raw

PATCH 218/272 md: Fix removal of extra drives when converting RAID6 to RAID5

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: NeilBrown <[email protected]>

commit bf2cb0dab8c97f00a71875d9b13dbac17a2f47ca upstream.

When a RAID6 is converted to a RAID5, the extra drive should be discarded. However it isn't due to a typo in a comparison.

This bug was introduced in commit e93f68a1fc6 in 2.6.35-rc4 and is suitable for any -stable since than.

As the extra drive is not removed, the 'degraded' counter is wrong and so the RAID5 will not respond correctly to a subsequent failure.

---
 drivers/md/md.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/md/md.c +1 -1
@@ -3117,7 +3117,7 @@ level_store(mddev_t *mddev, const char *
 		char nm[20];
 		if (rdev->raid_disk < 0)
 			continue;
-		if (rdev->new_raid_disk > mddev->raid_disks)
+		if (rdev->new_raid_disk >= mddev->raid_disks)
 			rdev->new_raid_disk = -1;
 		if (rdev->new_raid_disk == rdev->raid_disk)
 			continue;
author
#219 lore raw

PATCH 219/272 pata_mpc52xx: inherit from ata_bmdma_port_ops

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Tejun Heo <[email protected]>

commit 77c5fd19075d299fe820bb59bb21b0b113676e20 upstream.

pata_mpc52xx supports BMDMA but inherits ata_sff_port_ops which triggers BUG_ON() when a DMA command is issued. Fix it.

---
 drivers/ata/pata_mpc52xx.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ata/pata_mpc52xx.c +1 -1
@@ -610,7 +610,7 @@ static struct scsi_host_template mpc52xx
 };
 
 static struct ata_port_operations mpc52xx_ata_port_ops = {
-	.inherits		= &ata_sff_port_ops,
+	.inherits		= &ata_bmdma_port_ops,
 	.sff_dev_select		= mpc52xx_ata_dev_select,
 	.set_piomode		= mpc52xx_ata_set_piomode,
 	.set_dmamode		= mpc52xx_ata_set_dmamode,
author
#220 lore raw

PATCH 220/272 md_make_request: dont touch the bio after calling make_request

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Chris Mason <[email protected]>

commit e91ece5590b3c728624ab57043fc7a05069c604a upstream.

md_make_request was calling bio_sectors() for part_stat_add after it was calling the make_request function. This is bad because the make_request function can free the bio and because the bi_size field can change around.

The fix here was suggested by Jens Axboe. It saves the sector count before the make_request call. I hit this with CONFIG_DEBUG_PAGEALLOC turned on while trying to break his pretty fusionio card.

---
 drivers/md/md.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/md/md.c +7 -2
@@ -287,6 +287,7 @@ static int md_make_request(struct reques
 	mddev_t *mddev = q->queuedata;
 	int rv;
 	int cpu;
+	unsigned int sectors;
 
 	if (mddev == NULL || mddev->pers == NULL
 	    || !mddev->ready) {
@@ -311,12 +312,16 @@ static int md_make_request(struct reques
 	atomic_inc(&mddev->active_io);
 	rcu_read_unlock();
 
+	/*
+	 * save the sectors now since our bio can
+	 * go away inside make_request
+	 */
+	sectors = bio_sectors(bio);
 	rv = mddev->pers->make_request(mddev, bio);
 
 	cpu = part_stat_lock();
 	part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]);
-	part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw],
-		      bio_sectors(bio));
+	part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], sectors);
 	part_stat_unlock();
 
 	if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended)
author
#221 lore raw

PATCH 221/272 PM / Runtime: Dont enable interrupts while running in_interrupt

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Alan Stern <[email protected]>

commit c3810c88788d505d4ffd786addd111b745e42161 upstream.

This patch (as1445) fixes a bug in the runtime PM core left over from the addition of the no_callbacks flag. If this flag is set then it is possible for rpm_suspend() to be called in_interrupt, so when releasing spinlocks it's important not to re-enable interrupts.

To avoid an unnecessary save-and-restore of the interrupt flag, the patch also inlines a pm_request_idle() call.

This fixes Bugzilla #27482.

(The offending code was added in 2.6.37, so it's not necessary to apply this to any earlier stable kernels.)

---
 drivers/base/power/runtime.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/base/power/runtime.c +6 -3
@@ -404,12 +404,15 @@ static int rpm_suspend(struct device *de
 		goto out;
 	}
 
+	/* Maybe the parent is now able to suspend. */
 	if (parent && !parent->power.ignore_children) {
-		spin_unlock_irq(&dev->power.lock);
+		spin_unlock(&dev->power.lock);
 
-		pm_request_idle(parent);
+		spin_lock(&parent->power.lock);
+		rpm_idle(parent, RPM_ASYNC);
+		spin_unlock(&parent->power.lock);
 
-		spin_lock_irq(&dev->power.lock);
+		spin_lock(&dev->power.lock);
 	}
 
  out:
author
#222 lore raw

PATCH 222/272 net: clear heap allocation for ethtool_get_regs()

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Eugene Teo <[email protected]>

commit b7c7d01aaed1f71d9afe815a569f0a81465a1744 upstream.

There is a conflict between commit b00916b1 and a77f5db3. This patch resolves the conflict by clearing the heap allocation in ethtool_get_regs().

---
 net/core/ethtool.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/ethtool.c +1 -1
@@ -817,7 +817,7 @@ static int ethtool_get_regs(struct net_d
 	if (regs.len > reglen)
 		regs.len = reglen;
 
-	regbuf = vmalloc(reglen);
+	regbuf = vzalloc(reglen);
 	if (!regbuf)
 		return -ENOMEM;
 
author
#223 lore raw

PATCH 223/272 nilfs2: fix crash after one superblock became unavailable

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Ryusuke Konishi <[email protected]>

commit 0ca7a5b9ac5d301845dd6382ff25a699b6263a81 upstream.

Fixes the following kernel oops in nilfs_setup_super() which could arise if one of two super-blocks is unavailable.

Quoted 9 lines
BUG: unable to handle kernel NULL pointer dereference at   (null)
Pid: 3529, comm: mount.nilfs2 Not tainted 2.6.37 #1 /
EIP: 0060:[<c03196bc>] EFLAGS: 00010202 CPU: 3
EIP is at memcpy+0xc/0x1b
Call Trace:
 [<f953720e>] ? nilfs_setup_super+0x6c/0xa5 [nilfs2]
 [<f95369e9>] ? nilfs_get_root_dentry+0x81/0xcb [nilfs2]
 [<f9537a08>] ? nilfs_mount+0x4f9/0x62c [nilfs2]
 [<c02745cf>] ? kstrdup+0x36/0x3f
Quoted 8 lines
 [<f953750f>] ? nilfs_mount+0x0/0x62c [nilfs2]
 [<c0293940>] ? vfs_kern_mount+0x4d/0x12c
 [<c02a5100>] ? get_fs_type+0x76/0x8f
 [<c0293a68>] ? do_kern_mount+0x33/0xbf
 [<c02a784a>] ? do_mount+0x2ed/0x714
 [<c02a6171>] ? copy_mount_options+0x28/0xfc
 [<c02a7ce3>] ? sys_mount+0x72/0xaf
 [<c0473085>] ? syscall_call+0x7/0xb

LKML-Reference: <[email protected]>

---
 fs/nilfs2/super.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
fs/nilfs2/super.c +2 -1
@@ -688,7 +688,8 @@ skip_mount_setup:
 	sbp[0]->s_state =
 		cpu_to_le16(le16_to_cpu(sbp[0]->s_state) & ~NILFS_VALID_FS);
 	/* synchronize sbp[1] with sbp[0] */
-	memcpy(sbp[1], sbp[0], nilfs->ns_sbsize);
+	if (sbp[1])
+		memcpy(sbp[1], sbp[0], nilfs->ns_sbsize);
 	return nilfs_commit_super(sbi, NILFS_SB_COMMIT_ALL);
 }
 
author
#224 lore raw

PATCH 224/272 tpm: fix panic caused by "tpm: Autodetect itpm devices"

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Olof Johansson <[email protected]>

commit e5cce6c13c25d9ac56955a3ae2fd562719848172 upstream.

commit 3f0d3d016d89a5efb8b926d4707eb21fa13f3d27 adds a check for PNP device id to the common tpm_tis_init() function, which in some cases (force=1) will be called without the device being a member of a pnp_dev. Oopsing and panics ensue.

Move the test up to before the call to tpm_tis_init(), since it just modifies a global variable anyway.

---
 drivers/char/tpm/tpm_tis.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/char/tpm/tpm_tis.c +3 -3
@@ -493,9 +493,6 @@ static int tpm_tis_init(struct device *d
 		 "1.2 TPM (device-id 0x%X, rev-id %d)\n",
 		 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
 
-	if (is_itpm(to_pnp_dev(dev)))
-		itpm = 1;
-
 	if (itpm)
 		dev_info(dev, "Intel iTPM workaround enabled\n");
 
@@ -637,6 +634,9 @@ static int __devinit tpm_tis_pnp_init(st
 	else
 		interrupts = 0;
 
+	if (is_itpm(pnp_dev))
+		itpm = 1;
+
 	return tpm_tis_init(&pnp_dev->dev, start, len, irq);
 }
 
author
#225 lore raw

PATCH 225/272 TPM: Long default timeout fix

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Rajiv Andrade <[email protected]>

commit c4ff4b829ef9e6353c0b133b7adb564a68054979 upstream.

If duration variable value is 0 at this point, it's because chip->vendor.duration wasn't filled by tpm_get_timeouts() yet. This patch sets then the lowest timeout just to give enough time for tpm_get_timeouts() to further succeed.

This fix avoids long boot times in case another entity attempts to send commands to the TPM when the TPM isn't accessible.

---
 drivers/char/tpm/tpm.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/char/tpm/tpm.c +6 -4
@@ -364,12 +364,14 @@ unsigned long tpm_calc_ordinal_duration(
 		    tpm_protected_ordinal_duration[ordinal &
 						   TPM_PROTECTED_ORDINAL_MASK];
 
-	if (duration_idx != TPM_UNDEFINED)
+	if (duration_idx != TPM_UNDEFINED) {
 		duration = chip->vendor.duration[duration_idx];
-	if (duration <= 0)
+		/* if duration is 0, it's because chip->vendor.duration wasn't */
+		/* filled yet, so we set the lowest timeout just to give enough */
+		/* time for tpm_get_timeouts() to succeed */
+		return (duration <= 0 ? HZ : duration);
+	} else
 		return 2 * 60 * HZ;
-	else
-		return duration;
 }
 EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
 
author
#226 lore raw

PATCH 226/272 tpm_tis: Use timeouts returned from TPM

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Stefan Berger <[email protected]>

commit 9b29050f8f75916f974a2d231ae5d3cd59792296 upstream.

The current TPM TIS driver in git discards the timeout values returned from the TPM. The check of the response packet needs to consider that the return_code field is 0 on success and the size of the expected packet is equivalent to the header size + u32 length indicator for the TPM_GetCapability() result + 3 timeout indicators of type u32.

I am also adding a sysfs entry 'timeouts' showing the timeouts that are being used.

---
 drivers/char/tpm/tpm.c     |   18 ++++++++++++++++--
 drivers/char/tpm/tpm.h     |    2 ++
 drivers/char/tpm/tpm_tis.c |    4 +++-
 3 files changed, 21 insertions(+), 3 deletions(-)
drivers/char/tpm/tpm.c +16 -2
@@ -577,9 +577,11 @@ duration:
 	if (rc)
 		return;
 
-	if (be32_to_cpu(tpm_cmd.header.out.return_code)
-	    != 3 * sizeof(u32))
+	if (be32_to_cpu(tpm_cmd.header.out.return_code) != 0 ||
+	    be32_to_cpu(tpm_cmd.header.out.length)
+	    != sizeof(tpm_cmd.header.out) + sizeof(u32) + 3 * sizeof(u32))
 		return;
+
 	duration_cap = &tpm_cmd.params.getcap_out.cap.duration;
 	chip->vendor.duration[TPM_SHORT] =
 	    usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_short));
@@ -923,6 +925,18 @@ ssize_t tpm_show_caps_1_2(struct device
 }
 EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
 
+ssize_t tpm_show_timeouts(struct device *dev, struct device_attribute *attr,
+			  char *buf)
+{
+	struct tpm_chip *chip = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d %d %d\n",
+	               jiffies_to_usecs(chip->vendor.duration[TPM_SHORT]),
+	               jiffies_to_usecs(chip->vendor.duration[TPM_MEDIUM]),
+	               jiffies_to_usecs(chip->vendor.duration[TPM_LONG]));
+}
+EXPORT_SYMBOL_GPL(tpm_show_timeouts);
+
 ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
 			const char *buf, size_t count)
 {
drivers/char/tpm/tpm.h +2 -0
@@ -56,6 +56,8 @@ extern ssize_t tpm_show_owned(struct dev
 				char *);
 extern ssize_t tpm_show_temp_deactivated(struct device *,
 					 struct device_attribute *attr, char *);
+extern ssize_t tpm_show_timeouts(struct device *,
+				 struct device_attribute *attr, char *);
 
 struct tpm_chip;
 
drivers/char/tpm/tpm_tis.c +3 -1
@@ -376,6 +376,7 @@ static DEVICE_ATTR(temp_deactivated, S_I
 		   NULL);
 static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
 static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
+static DEVICE_ATTR(timeouts, S_IRUGO, tpm_show_timeouts, NULL);
 
 static struct attribute *tis_attrs[] = {
 	&dev_attr_pubek.attr,
@@ -385,7 +386,8 @@ static struct attribute *tis_attrs[] = {
 	&dev_attr_owned.attr,
 	&dev_attr_temp_deactivated.attr,
 	&dev_attr_caps.attr,
-	&dev_attr_cancel.attr, NULL,
+	&dev_attr_cancel.attr,
+	&dev_attr_timeouts.attr, NULL,
 };
 
 static struct attribute_group tis_attr_grp = {
author
#227 lore raw

PATCH 227/272 SELinux: define permissions for DCB netlink messages

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Eric Paris <[email protected]>

commit 350e4f31e0eaf56dfc3b328d24a11bdf42a41fb8 upstream.

Commit 2f90b865 added two new netlink message types to the netlink route socket. SELinux has hooks to define if netlink messages are allowed to be sent or received, but it did not know about these two new message types. By default we allow such actions so noone likely noticed. This patch adds the proper definitions and thus proper permissions enforcement.

---
 security/selinux/nlmsgtab.c |    2 ++
 1 file changed, 2 insertions(+)
security/selinux/nlmsgtab.c +2 -0
@@ -65,6 +65,8 @@ static struct nlmsg_perm nlmsg_route_per
 	{ RTM_NEWADDRLABEL,	NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
 	{ RTM_DELADDRLABEL,	NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
 	{ RTM_GETADDRLABEL,	NETLINK_ROUTE_SOCKET__NLMSG_READ  },
+	{ RTM_GETDCB,		NETLINK_ROUTE_SOCKET__NLMSG_READ  },
+	{ RTM_SETDCB,		NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
 };
 
 static struct nlmsg_perm nlmsg_firewall_perms[] =
author
#228 lore raw

PATCH 228/272 SELinux: do not compute transition labels on mountpoint labeled filesystems

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Eric Paris <[email protected]>

commit 415103f9932d45f7927f4b17e3a9a13834cdb9a1 upstream.

selinux_inode_init_security computes transitions sids even for filesystems that use mount point labeling. It shouldn't do that. It should just use the mount point label always and no matter what.

This causes 2 problems. 1) it makes file creation slower than it needs to be since we calculate the transition sid and 2) it allows files to be created with a different label than the mount point!

# id -Z
staff_u:sysadm_r:sysadm_t:s0-s0:c0.c1023
# sesearch --type --class file --source sysadm_t --target tmp_t
Found 1 semantic te rules:
   type_transition sysadm_t tmp_t : file user_tmp_t;
# mount -o loop,context="system_u:object_r:tmp_t:s0"  /tmp/fs /mnt/tmp
# ls -lZ /mnt/tmp
drwx------. root root system_u:object_r:tmp_t:s0       lost+found
# touch /mnt/tmp/file1
# ls -lZ /mnt/tmp
-rw-r--r--. root root staff_u:object_r:user_tmp_t:s0   file1
drwx------. root root system_u:object_r:tmp_t:s0       lost+found

Whoops, we have a mount point labeled filesystem tmp_t with a user_tmp_t labeled file!

---
 security/selinux/hooks.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
security/selinux/hooks.c +4 -1
@@ -2525,7 +2525,10 @@ static int selinux_inode_init_security(s
 	sid = tsec->sid;
 	newsid = tsec->create_sid;
 
-	if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
+	if ((sbsec->flags & SE_SBINITIALIZED) &&
+	    (sbsec->behavior == SECURITY_FS_USE_MNTPOINT))
+		newsid = sbsec->mntpoint_sid;
+	else if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
 		rc = security_transition_sid(sid, dsec->sid,
 					     inode_mode_to_security_class(inode->i_mode),
 					     &newsid);
author
#229 lore raw

PATCH 229/272 watchdog: Fix broken nowatchdog logic

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Marcin Slusarz <[email protected]>

commit 4135038a582c20ffdadfcf6564852e0b72a20968 upstream.

Passing nowatchdog to kernel disables 2 things: creation of watchdog threads AND initialization of percpu watchdog_hrtimer. As hrtimers are initialized only at boot it's not possible to enable watchdog later - for me all watchdog threads started to eat 100% of CPU time, but they could just crash.

Additionally, even if these threads would start properly, watchdog_disable_all_cpus was guarded by no_watchdog check, so you couldn't disable watchdog.

To fix this, remove no_watchdog variable and use already existing watchdog_enabled variable.

[ removed another no_watchdog instance ]
Cc Stephane Eranian <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Frederic Weisbecker <[email protected]>

LKML-Reference: <[email protected]>

---
 kernel/watchdog.c |   18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)
kernel/watchdog.c +5 -13
@@ -27,7 +27,7 @@
 #include <asm/irq_regs.h>
 #include <linux/perf_event.h>
 
-int watchdog_enabled;
+int watchdog_enabled = 1;
 int __read_mostly softlockup_thresh = 60;
 
 static DEFINE_PER_CPU(unsigned long, watchdog_touch_ts);
@@ -43,9 +43,6 @@ static DEFINE_PER_CPU(unsigned long, hrt
 static DEFINE_PER_CPU(struct perf_event *, watchdog_ev);
 #endif
 
-static int no_watchdog;
-
-
 /* boot commands */
 /*
  * Should we panic when a soft-lockup or hard-lockup occurs:
@@ -75,7 +72,7 @@ __setup("softlockup_panic=", softlockup_
 
 static int __init nowatchdog_setup(char *str)
 {
-	no_watchdog = 1;
+	watchdog_enabled = 0;
 	return 1;
 }
 __setup("nowatchdog", nowatchdog_setup);
@@ -83,7 +80,7 @@ __setup("nowatchdog", nowatchdog_setup);
 /* deprecated */
 static int __init nosoftlockup_setup(char *str)
 {
-	no_watchdog = 1;
+	watchdog_enabled = 0;
 	return 1;
 }
 __setup("nosoftlockup", nosoftlockup_setup);
@@ -475,9 +472,6 @@ static void watchdog_disable_all_cpus(vo
 {
 	int cpu;
 
-	if (no_watchdog)
-		return;
-
 	for_each_online_cpu(cpu)
 		watchdog_disable(cpu);
 
@@ -531,7 +525,8 @@ cpu_callback(struct notifier_block *nfb,
 		break;
 	case CPU_ONLINE:
 	case CPU_ONLINE_FROZEN:
-		err = watchdog_enable(hotcpu);
+		if (watchdog_enabled)
+			err = watchdog_enable(hotcpu);
 		break;
 #ifdef CONFIG_HOTPLUG_CPU
 	case CPU_UP_CANCELED:
@@ -556,9 +551,6 @@ static int __init spawn_watchdog_task(vo
 	void *cpu = (void *)(long)smp_processor_id();
 	int err;
 
-	if (no_watchdog)
-		return 0;
-
 	err = cpu_callback(&cpu_nfb, CPU_UP_PREPARE, cpu);
 	WARN_ON(notifier_to_errno(err));
 
author
#230 lore raw

PATCH 230/272 Input: sysrq - rework re-inject logic

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Dmitry Torokhov <[email protected]>

commit 7ab7b5adfb923978a2cab7bd3fac9ccf7d21cc3f upstream.

Internally 'disable' the filter when re-injecting Alt-SysRq instead of relying on input core to suppress delivery of injected events to the originating handler.

This allows to revert commit 5fdbe44d033d059cc56c2803e6b4dbd8cb4e5e39 which causes problems with existing userspace programs trying to loopback the events via evdev.

---
 drivers/tty/sysrq.c |   17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)
drivers/tty/sysrq.c +16 -1
@@ -571,6 +571,7 @@ struct sysrq_state {
 	unsigned int alt_use;
 	bool active;
 	bool need_reinject;
+	bool reinjecting;
 };
 
 static void sysrq_reinject_alt_sysrq(struct work_struct *work)
@@ -581,6 +582,10 @@ static void sysrq_reinject_alt_sysrq(str
 	unsigned int alt_code = sysrq->alt_use;
 
 	if (sysrq->need_reinject) {
+		/* we do not want the assignment to be reordered */
+		sysrq->reinjecting = true;
+		mb();
+
 		/* Simulate press and release of Alt + SysRq */
 		input_inject_event(handle, EV_KEY, alt_code, 1);
 		input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1);
@@ -589,6 +594,9 @@ static void sysrq_reinject_alt_sysrq(str
 		input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0);
 		input_inject_event(handle, EV_KEY, alt_code, 0);
 		input_inject_event(handle, EV_SYN, SYN_REPORT, 1);
+
+		mb();
+		sysrq->reinjecting = false;
 	}
 }
 
@@ -599,6 +607,13 @@ static bool sysrq_filter(struct input_ha
 	bool was_active = sysrq->active;
 	bool suppress;
 
+	/*
+	 * Do not filter anything if we are in the process of re-injecting
+	 * Alt+SysRq combination.
+	 */
+	if (sysrq->reinjecting)
+		return false;
+
 	switch (type) {
 
 	case EV_SYN:
@@ -629,7 +644,7 @@ static bool sysrq_filter(struct input_ha
 				sysrq->alt_use = sysrq->alt;
 				/*
 				 * If nothing else will be pressed we'll need
-				 * to * re-inject Alt-SysRq keysroke.
+				 * to re-inject Alt-SysRq keysroke.
 				 */
 				sysrq->need_reinject = true;
 			}
author
#231 lore raw

PATCH 231/272 Revert "Input: do not pass injected events back to the originating handler"

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Dmitry Torokhov <[email protected]>

commit 9ae4345a46bdb148e32a547e89ff29563a11e127 upstream.

This reverts commit 5fdbe44d033d059cc56c2803e6b4dbd8cb4e5e39.

Apparently there exist userspace programs that expect to be able to "loop back" and distribute to readers events written into /dev/input/eventX and this change made for the benefit of SysRq handler broke them. Now that SysRq uses alternative method to suppress filtering of the events it re-injects we can safely revert this change.

---
 drivers/input/input.c |   37 +++++++++++--------------------------
 1 file changed, 11 insertions(+), 26 deletions(-)
drivers/input/input.c +11 -26
@@ -73,7 +73,6 @@ static int input_defuzz_abs_event(int va
  * dev->event_lock held and interrupts disabled.
  */
 static void input_pass_event(struct input_dev *dev,
-			     struct input_handler *src_handler,
 			     unsigned int type, unsigned int code, int value)
 {
 	struct input_handler *handler;
@@ -92,15 +91,6 @@ static void input_pass_event(struct inpu
 				continue;
 
 			handler = handle->handler;
-
-			/*
-			 * If this is the handler that injected this
-			 * particular event we want to skip it to avoid
-			 * filters firing again and again.
-			 */
-			if (handler == src_handler)
-				continue;
-
 			if (!handler->filter) {
 				if (filtered)
 					break;
@@ -130,7 +120,7 @@ static void input_repeat_key(unsigned lo
 	if (test_bit(dev->repeat_key, dev->key) &&
 	    is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) {
 
-		input_pass_event(dev, NULL, EV_KEY, dev->repeat_key, 2);
+		input_pass_event(dev, EV_KEY, dev->repeat_key, 2);
 
 		if (dev->sync) {
 			/*
@@ -139,7 +129,7 @@ static void input_repeat_key(unsigned lo
 			 * Otherwise assume that the driver will send
 			 * SYN_REPORT once it's done.
 			 */
-			input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
+			input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
 		}
 
 		if (dev->rep[REP_PERIOD])
@@ -172,7 +162,6 @@ static void input_stop_autorepeat(struct
 #define INPUT_PASS_TO_ALL	(INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE)
 
 static int input_handle_abs_event(struct input_dev *dev,
-				  struct input_handler *src_handler,
 				  unsigned int code, int *pval)
 {
 	bool is_mt_event;
@@ -216,15 +205,13 @@ static int input_handle_abs_event(struct
 	/* Flush pending "slot" event */
 	if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) {
 		input_abs_set_val(dev, ABS_MT_SLOT, dev->slot);
-		input_pass_event(dev, src_handler,
-				 EV_ABS, ABS_MT_SLOT, dev->slot);
+		input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot);
 	}
 
 	return INPUT_PASS_TO_HANDLERS;
 }
 
 static void input_handle_event(struct input_dev *dev,
-			       struct input_handler *src_handler,
 			       unsigned int type, unsigned int code, int value)
 {
 	int disposition = INPUT_IGNORE_EVENT;
@@ -277,8 +264,7 @@ static void input_handle_event(struct in
 
 	case EV_ABS:
 		if (is_event_supported(code, dev->absbit, ABS_MAX))
-			disposition = input_handle_abs_event(dev, src_handler,
-							     code, &value);
+			disposition = input_handle_abs_event(dev, code, &value);
 
 		break;
 
@@ -336,7 +322,7 @@ static void input_handle_event(struct in
 		dev->event(dev, type, code, value);
 
 	if (disposition & INPUT_PASS_TO_HANDLERS)
-		input_pass_event(dev, src_handler, type, code, value);
+		input_pass_event(dev, type, code, value);
 }
 
 /**
@@ -365,7 +351,7 @@ void input_event(struct input_dev *dev,
 
 		spin_lock_irqsave(&dev->event_lock, flags);
 		add_input_randomness(type, code, value);
-		input_handle_event(dev, NULL, type, code, value);
+		input_handle_event(dev, type, code, value);
 		spin_unlock_irqrestore(&dev->event_lock, flags);
 	}
 }
@@ -395,8 +381,7 @@ void input_inject_event(struct input_han
 		rcu_read_lock();
 		grab = rcu_dereference(dev->grab);
 		if (!grab || grab == handle)
-			input_handle_event(dev, handle->handler,
-					   type, code, value);
+			input_handle_event(dev, type, code, value);
 		rcu_read_unlock();
 
 		spin_unlock_irqrestore(&dev->event_lock, flags);
@@ -609,10 +594,10 @@ static void input_dev_release_keys(struc
 		for (code = 0; code <= KEY_MAX; code++) {
 			if (is_event_supported(code, dev->keybit, KEY_MAX) &&
 			    __test_and_clear_bit(code, dev->key)) {
-				input_pass_event(dev, NULL, EV_KEY, code, 0);
+				input_pass_event(dev, EV_KEY, code, 0);
 			}
 		}
-		input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
+		input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
 	}
 }
 
@@ -887,9 +872,9 @@ int input_set_keycode(struct input_dev *
 	    !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
 	    __test_and_clear_bit(old_keycode, dev->key)) {
 
-		input_pass_event(dev, NULL, EV_KEY, old_keycode, 0);
+		input_pass_event(dev, EV_KEY, old_keycode, 0);
 		if (dev->sync)
-			input_pass_event(dev, NULL, EV_SYN, SYN_REPORT, 1);
+			input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
 	}
 
  out:
author
#232 lore raw

PATCH 232/272 Input: sysrq - ensure sysrq_enabled and __sysrq_enabled are consistent

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Andy Whitcroft <[email protected]>

commit 8c6a98b22b750c9eb52653ba643faa17db8d3881 upstream.

Currently sysrq_enabled and __sysrq_enabled are initialised separately and inconsistently, leading to sysrq being actually enabled by reported as not enabled in sysfs. The first change to the sysfs configurable synchronises these two:

    static int __read_mostly sysrq_enabled = 1;
    static int __sysrq_enabled;

Add a common define to carry the default for these preventing them becoming out of sync again. Default this to 1 to mirror previous behaviour.

---
 drivers/tty/sysrq.c   |    2 +-
 include/linux/sysrq.h |    3 +++
 kernel/sysctl.c       |    3 ++-
 3 files changed, 6 insertions(+), 2 deletions(-)
drivers/tty/sysrq.c +1 -1
@@ -46,7 +46,7 @@
 #include <asm/irq_regs.h>
 
 /* Whether we react on sysrq keys or just ignore them */
-static int __read_mostly sysrq_enabled = 1;
+static int __read_mostly sysrq_enabled = SYSRQ_DEFAULT_ENABLE;
 static bool __read_mostly sysrq_always_enabled;
 
 static bool sysrq_on(void)
include/linux/sysrq.h +3 -0
@@ -17,6 +17,9 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 
+/* Enable/disable SYSRQ support by default (0==no, 1==yes). */
+#define SYSRQ_DEFAULT_ENABLE	1
+
 /* Possible values of bitmask for enabling sysrq functions */
 /* 0x0001 is reserved for enable everything */
 #define SYSRQ_ENABLE_LOG	0x0002
kernel/sysctl.c +2 -1
@@ -169,7 +169,8 @@ static int proc_taint(struct ctl_table *
 #endif
 
 #ifdef CONFIG_MAGIC_SYSRQ
-static int __sysrq_enabled; /* Note: sysrq code ises it's own private copy */
+/* Note: sysrq code uses it's own private copy */
+static int __sysrq_enabled = SYSRQ_DEFAULT_ENABLE;
 
 static int sysrq_sysctl_handler(ctl_table *table, int write,
 				void __user *buffer, size_t *lenp,
author
#233 lore raw

PATCH 233/272 oprofile: Fix usage of CONFIG_HW_PERF_EVENTS for oprofile_perf_init and friends

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Ari Kauppi <[email protected]>

commit 1ea1bdf7faa4d0b5293e605f2e1ef1c2c59f6b53 upstream.

The implementations are flagged in Makefile with CONFIG_HW_PERF_EVENTS instead of CONFIG_PERF_EVENTS.

---
 include/linux/oprofile.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/oprofile.h +2 -2
@@ -186,10 +186,10 @@ int oprofile_add_data(struct op_entry *e
 int oprofile_add_data64(struct op_entry *entry, u64 val);
 int oprofile_write_commit(struct op_entry *entry);
 
-#ifdef CONFIG_PERF_EVENTS
+#ifdef CONFIG_HW_PERF_EVENTS
 int __init oprofile_perf_init(struct oprofile_operations *ops);
 void oprofile_perf_exit(void);
 char *op_name_from_perf_id(void);
-#endif /* CONFIG_PERF_EVENTS */
+#endif /* CONFIG_HW_PERF_EVENTS */
 
 #endif /* OPROFILE_H */
author
#234 lore raw

PATCH 234/272 x86, dmi, debug: Log board name (when present) in dmesg/oops output

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Naga Chumbalkar <[email protected]>

commit 84e383b322e5348db03be54ff64cc6da87003717 upstream.

The "Type 2" SMBIOS record that contains Board Name is not strictly required and may be absent in the SMBIOS on some platforms.

( Please note that Type 2 is not listed in Table 3 in Sec 6.2
("Required Structures and Data") of the SMBIOS v2.7 Specification. )

Use the Manufacturer Name (aka System Vendor) name. Print Board Name only when it is present.

Before the fix:
(i) dmesg output: DMI: /ProLiant DL380 G6, BIOS P62 01/29/2011
(ii) oops output: Pid: 2170, comm: bash Not tainted 2.6.38-rc4+ #3 /ProLiant DL380 G6

After the fix:
(i) dmesg output: DMI: HP ProLiant DL380 G6, BIOS P62 01/29/2011
(ii) oops output: Pid: 2278, comm: bash Not tainted 2.6.38-rc4+ #4 HP ProLiant DL380 G6

LKML-Reference: <20110214224423.2182.13929.sendpatchset@nchumbalkar.americas.hpqcorp.net>

---
 arch/x86/kernel/process.c   |   22 ++++++++++++++++------
 drivers/firmware/dmi_scan.c |   11 +++++++++--
 2 files changed, 25 insertions(+), 8 deletions(-)
arch/x86/kernel/process.c +16 -6
@@ -97,21 +97,31 @@ void show_regs(struct pt_regs *regs)
 
 void show_regs_common(void)
 {
-	const char *board, *product;
+	const char *vendor, *product, *board;
 
-	board = dmi_get_system_info(DMI_BOARD_NAME);
-	if (!board)
-		board = "";
+	vendor = dmi_get_system_info(DMI_SYS_VENDOR);
+	if (!vendor)
+		vendor = "";
 	product = dmi_get_system_info(DMI_PRODUCT_NAME);
 	if (!product)
 		product = "";
 
+	/* Board Name is optional */
+	board = dmi_get_system_info(DMI_BOARD_NAME);
+
 	printk(KERN_CONT "\n");
-	printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s %s/%s\n",
+	printk(KERN_DEFAULT "Pid: %d, comm: %.20s %s %s %.*s",
 		current->pid, current->comm, print_tainted(),
 		init_utsname()->release,
 		(int)strcspn(init_utsname()->version, " "),
-		init_utsname()->version, board, product);
+		init_utsname()->version);
+	printk(KERN_CONT " ");
+	printk(KERN_CONT "%s %s", vendor, product);
+	if (board) {
+		printk(KERN_CONT "/");
+		printk(KERN_CONT "%s", board);
+	}
+	printk(KERN_CONT "\n");
 }
 
 void flush_thread(void)
drivers/firmware/dmi_scan.c +9 -2
@@ -378,10 +378,17 @@ static void __init print_filtered(const
 
 static void __init dmi_dump_ids(void)
 {
+	const char *board;	/* Board Name is optional */
+
 	printk(KERN_DEBUG "DMI: ");
-	print_filtered(dmi_get_system_info(DMI_BOARD_NAME));
-	printk(KERN_CONT "/");
+	print_filtered(dmi_get_system_info(DMI_SYS_VENDOR));
+	printk(KERN_CONT " ");
 	print_filtered(dmi_get_system_info(DMI_PRODUCT_NAME));
+	board = dmi_get_system_info(DMI_BOARD_NAME);
+	if (board) {
+		printk(KERN_CONT "/");
+		print_filtered(board);
+	}
 	printk(KERN_CONT ", BIOS ");
 	print_filtered(dmi_get_system_info(DMI_BIOS_VERSION));
 	printk(KERN_CONT " ");
author
#235 lore raw

PATCH 235/272 x86: Readd missing irq_to_desc() in fixup_irq()

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Thomas Gleixner <[email protected]>

commit 5117348dea5e3ecbb785cfa1271386fb49332b41 upstream.

commit a3c08e5d(x86: Convert irq_chip access to new functions) accidentally zapped desc = irq_to_desc(irq); in the vector loop. So we lock some random irq descriptor.

Add it back.

---
 arch/x86/kernel/irq.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/x86/kernel/irq.c +2 -1
@@ -357,7 +357,8 @@ void fixup_irqs(void)
 		if (irr  & (1 << (vector % 32))) {
 			irq = __get_cpu_var(vector_irq)[vector];
 
-			data = irq_get_irq_data(irq);
+			desc = irq_to_desc(irq);
+			data = &desc->irq_data;
 			raw_spin_lock(&desc->lock);
 			if (data->chip->irq_retrigger)
 				data->chip->irq_retrigger(data);
author
#236 lore raw

PATCH 236/272 mtd: pxa3xx_nand: NULL dereference in pxa3xx_nand_probe

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Dan Carpenter <[email protected]>

commit 52d039fdaa78c5a9f9bc2940ad58d7ed76b8336d upstream.

"info->cmdset" gets dereferenced in __readid() so it needs to be initialized earlier in the function. This bug was introduced in 18c81b1828f8 "mtd: pxa3xx_nand: remove the flash info in driver structure".

---
 drivers/mtd/nand/pxa3xx_nand.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/nand/pxa3xx_nand.c +1 -1
@@ -885,6 +885,7 @@ static int pxa3xx_nand_detect_config(str
 	/* set info fields needed to __readid */
 	info->read_id_bytes = (info->page_size == 2048) ? 4 : 2;
 	info->reg_ndcr = ndcr;
+	info->cmdset = &default_cmdset;
 
 	if (__readid(info, &id))
 		return -ENODEV;
@@ -915,7 +916,6 @@ static int pxa3xx_nand_detect_config(str
 
 	info->ndtr0cs0 = nand_readl(info, NDTR0CS0);
 	info->ndtr1cs0 = nand_readl(info, NDTR1CS0);
-	info->cmdset = &default_cmdset;
 
 	return 0;
 }
author
#237 lore raw

PATCH 237/272 ieee80211: correct IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK macro

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Amitkumar Karwar <[email protected]>

commit 8d661f1e462d50bd83de87ee628aaf820ce3c66c upstream.

It is defined in include/linux/ieee80211.h. As per IEEE spec. bit6 to bit15 in block ack parameter represents buffer size. So the bitmask should be 0xFFC0.

---
 include/linux/ieee80211.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/ieee80211.h +1 -1
@@ -959,7 +959,7 @@ struct ieee80211_ht_info {
 /* block-ack parameters */
 #define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
 #define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
-#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0
+#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFC0
 #define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
 #define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
 
author
#238 lore raw

PATCH 238/272 dm: dont take i_mutex to change device size

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Mike Snitzer <[email protected]>

commit c217649bf2d60ac119afd71d938278cffd55962b upstream.

No longer needlessly hold md->bdev->bd_inode->i_mutex when changing the size of a DM device. This additional locking is unnecessary because i_size_write() is already protected by the existing critical section in dm_swap_table(). DM already has a reference on md->bdev so the associated bd_inode may be changed without lifetime concerns.

A negative side-effect of having held md->bdev->bd_inode->i_mutex was that a concurrent DM device resize and flush (via fsync) would deadlock. Dropping md->bdev->bd_inode->i_mutex eliminates this potential for deadlock. The following reproducer no longer deadlocks:
https://www.redhat.com/archives/dm-devel/2009-July/msg00284.html

---
 drivers/md/dm.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/md/dm.c +3 -2
@@ -1992,13 +1992,14 @@ static void event_callback(void *context
 	wake_up(&md->eventq);
 }
 
+/*
+ * Protected by md->suspend_lock obtained by dm_swap_table().
+ */
 static void __set_size(struct mapped_device *md, sector_t size)
 {
 	set_capacity(md->disk, size);
 
-	mutex_lock(&md->bdev->bd_inode->i_mutex);
 	i_size_write(md->bdev->bd_inode, (loff_t)size << SECTOR_SHIFT);
-	mutex_unlock(&md->bdev->bd_inode->i_mutex);
 }
 
 /*
author
#239 lore raw

PATCH 239/272 dm mpath: disable blk_abort_queue

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Mike Snitzer <[email protected]>

commit 09c9d4c9b6a2b5909ae3c6265e4cd3820b636863 upstream.

Revert commit 224cb3e981f1b2f9f93dbd49eaef505d17d894c2
dm: Call blk_abort_queue on failed paths

Multipath began to use blk_abort_queue() to allow for lower latency path deactivation. This was found to cause list corruption:

the cmd gets blk_abort_queued/timedout run on it and the scsi eh somehow is able to complete and run scsi_queue_insert while scsi_request_fn is still trying to process the request.

https://www.redhat.com/archives/dm-devel/2010-November/msg00085.html

---
 drivers/md/dm-mpath.c |   12 ------------
 1 file changed, 12 deletions(-)
drivers/md/dm-mpath.c +0 -12
@@ -33,7 +33,6 @@ struct pgpath {
 	unsigned fail_count;		/* Cumulative failure count */
 
 	struct dm_path path;
-	struct work_struct deactivate_path;
 	struct work_struct activate_path;
 };
 
@@ -116,7 +115,6 @@ static struct workqueue_struct *kmultipa
 static void process_queued_ios(struct work_struct *work);
 static void trigger_event(struct work_struct *work);
 static void activate_path(struct work_struct *work);
-static void deactivate_path(struct work_struct *work);
 
 
 /*-----------------------------------------------
@@ -129,7 +127,6 @@ static struct pgpath *alloc_pgpath(void)
 
 	if (pgpath) {
 		pgpath->is_active = 1;
-		INIT_WORK(&pgpath->deactivate_path, deactivate_path);
 		INIT_WORK(&pgpath->activate_path, activate_path);
 	}
 
@@ -141,14 +138,6 @@ static void free_pgpath(struct pgpath *p
 	kfree(pgpath);
 }
 
-static void deactivate_path(struct work_struct *work)
-{
-	struct pgpath *pgpath =
-		container_of(work, struct pgpath, deactivate_path);
-
-	blk_abort_queue(pgpath->path.dev->bdev->bd_disk->queue);
-}
-
 static struct priority_group *alloc_priority_group(void)
 {
 	struct priority_group *pg;
@@ -995,7 +984,6 @@ static int fail_path(struct pgpath *pgpa
 		      pgpath->path.dev->name, m->nr_valid_paths);
 
 	schedule_work(&m->trigger_event);
-	queue_work(kmultipathd, &pgpath->deactivate_path);
 
 out:
 	spin_unlock_irqrestore(&m->lock, flags);
author
#240 lore raw

PATCH 240/272 ARM: oprofile: Fix backtraces in timer mode

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Ari Kauppi <[email protected]>

commit d14dd7e20d5e526557f5d3cfef4046a642f80924 upstream.

Always allow backtraces when using oprofile on ARM, even if a PMU isn't present. Restores functionality originally introduced in commit 1b7b56982fdcd9d85effd76f3928cf5d6eb26155 ("oprofile: Always allow backtraces on ARM") by Richard Purdie.

It is not that obvious, but there is now only one oprofile_arch_init() function. So the .backtrace callback is available also in timer mode.

Implemented by removing code and using stubs for oprofile_perf_{init, exit} provided by <linux/oprofile.h>. This allows cleaning of other architecture specific implementations too.

arch/arm/oprofile/common.c +2 -10
index 8aa9744..2b66391 100644
@@ -10,8 +10,6 @@
  */
 
 #include <linux/cpumask.h>
-#include <linux/err.h>
-#include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
 #include <linux/oprofile.h>
@@ -46,6 +44,7 @@ char *op_name_from_perf_id(void)
 		return NULL;
 	}
 }
+#endif
 
 static int report_trace(struct stackframe *frame, void *d)
 {
@@ -111,6 +110,7 @@ static void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
 
 int __init oprofile_arch_init(struct oprofile_operations *ops)
 {
+	/* provide backtrace support also in timer mode: */
 	ops->backtrace		= arm_backtrace;
 
 	return oprofile_perf_init(ops);
@@ -120,11 +120,3 @@ void __exit oprofile_arch_exit(void)
 {
 	oprofile_perf_exit();
 }
-#else
-int __init oprofile_arch_init(struct oprofile_operations *ops)
-{
-	pr_info("oprofile: hardware counters not available\n");
-	return -ENODEV;
-}
-void __exit oprofile_arch_exit(void) {}
-#endif /* CONFIG_HW_PERF_EVENTS */
include/linux/oprofile.h +9 -0
index 54c8382..1ca6411 100644
@@ -16,6 +16,8 @@
 #include <linux/types.h>
 #include <linux/spinlock.h>
 #include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/printk.h>
 #include <asm/atomic.h>
  
 /* Each escaped entry is prefixed by ESCAPE_CODE
@@ -190,6 +192,13 @@ int oprofile_write_commit(struct op_entry *entry);
 int __init oprofile_perf_init(struct oprofile_operations *ops);
 void oprofile_perf_exit(void);
 char *op_name_from_perf_id(void);
+#else
+static inline int __init oprofile_perf_init(struct oprofile_operations *ops)
+{
+	pr_info("oprofile: hardware counters not available\n");
+	return -ENODEV;
+}
+static inline void oprofile_perf_exit(void) { }
 #endif /* CONFIG_HW_PERF_EVENTS */
 
 #endif /* OPROFILE_H */
author
#241 lore raw

PATCH 241/272 net/fec: fix MMFR_OP type in fec_enet_mdio_write

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Shawn Guo <[email protected]>

commit 862f0982eadcea0e114576c57ea426d3d51a69a6 upstream.

FEC_MMFR_OP_WRITE should be used than FEC_MMFR_OP_READ in a mdio write operation.

It's probably a typo introduced by commit:

e6b043d512fa8d9a3801bf5d72bfa3b8fc3b3cc8
netdev/fec.c: add phylib supporting to enable carrier detection (v2)

---
 drivers/net/fec.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/fec.c +2 -2
@@ -651,8 +651,8 @@ static int fec_enet_mdio_write(struct mi
 	fep->mii_timeout = 0;
 	init_completion(&fep->mdio_done);
 
-	/* start a read op */
-	writel(FEC_MMFR_ST | FEC_MMFR_OP_READ |
+	/* start a write op */
+	writel(FEC_MMFR_ST | FEC_MMFR_OP_WRITE |
 		FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(regnum) |
 		FEC_MMFR_TA | FEC_MMFR_DATA(value),
 		fep->hwp + FEC_MII_DATA);
author
#242 lore raw

PATCH 242/272 drm/radeon/kms: add quirk for Mac Radeon HD 2600 card

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Alex Deucher <[email protected]>

commit f598aa7593427ffe3a61e7767c34bd695a5e7ed0 upstream.

---
 drivers/gpu/drm/radeon/radeon_atombios.c |   11 +++++++++++
 1 file changed, 11 insertions(+)
drivers/gpu/drm/radeon/radeon_atombios.c +11 -0
@@ -388,6 +388,17 @@ static bool radeon_atom_apply_quirks(str
 			*line_mux = 0x90;
 	}
 
+	/* mac rv630 */
+	if ((dev->pdev->device == 0x9588) &&
+	    (dev->pdev->subsystem_vendor == 0x106b) &&
+	    (dev->pdev->subsystem_device == 0x00a6)) {
+		if ((supported_device == ATOM_DEVICE_TV1_SUPPORT) &&
+		    (*connector_type == DRM_MODE_CONNECTOR_DVII)) {
+			*connector_type = DRM_MODE_CONNECTOR_9PinDIN;
+			*line_mux = CONNECTOR_7PIN_DIN_ENUM_ID1;
+		}
+	}
+
 	/* ASUS HD 3600 XT board lists the DVI port as HDMI */
 	if ((dev->pdev->device == 0x9598) &&
 	    (dev->pdev->subsystem_vendor == 0x1043) &&
author
#243 lore raw

PATCH 243/272 drm/radeon/kms: adjust quirk for acer laptop

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Alex Deucher <[email protected]>

commit 2f299d5de02da3ffb1f9e1a05c91dcd1173ebd3c upstream.

Acer laptop (TravelMate 5730G) has an HDMI connector on the laptop and a DVI connector on the docking station and both share the same encoder, hpd pin, and ddc line. The bios connector table reflects this and is technically correct, however, we drop the DVI connector here since xrandr has no concept of encoders (only crtcs and connectors) and will try and drive both connectors with different crtcs which isn't possible on the hardware side and leaves no crtcs for LVDS or VGA.

Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=32732

---
 drivers/gpu/drm/radeon/radeon_atombios.c |   21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)
drivers/gpu/drm/radeon/radeon_atombios.c +11 -10
@@ -313,7 +313,6 @@ static bool radeon_atom_apply_quirks(str
 				     uint16_t *line_mux,
 				     struct radeon_hpd *hpd)
 {
-	struct radeon_device *rdev = dev->dev_private;
 
 	/* Asus M2A-VM HDMI board lists the DVI port as HDMI */
 	if ((dev->pdev->device == 0x791e) &&
@@ -436,21 +435,23 @@ static bool radeon_atom_apply_quirks(str
 		}
 	}
 
-	/* Acer laptop reports DVI-D as DVI-I and hpd pins reversed */
+	/* Acer laptop (Acer TravelMate 5730G) has an HDMI port
+	 * on the laptop and a DVI port on the docking station and
+	 * both share the same encoder, hpd pin, and ddc line.
+	 * So while the bios table is technically correct,
+	 * we drop the DVI port here since xrandr has no concept of
+	 * encoders and will try and drive both connectors
+	 * with different crtcs which isn't possible on the hardware
+	 * side and leaves no crtcs for LVDS or VGA.
+	 */
 	if ((dev->pdev->device == 0x95c4) &&
 	    (dev->pdev->subsystem_vendor == 0x1025) &&
 	    (dev->pdev->subsystem_device == 0x013c)) {
-		struct radeon_gpio_rec gpio;
-
 		if ((*connector_type == DRM_MODE_CONNECTOR_DVII) &&
 		    (supported_device == ATOM_DEVICE_DFP1_SUPPORT)) {
-			gpio = radeon_lookup_gpio(rdev, 6);
-			*hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio);
+			/* actually it's a DVI-D port not DVI-I */
 			*connector_type = DRM_MODE_CONNECTOR_DVID;
-		} else if ((*connector_type == DRM_MODE_CONNECTOR_HDMIA) &&
-			   (supported_device == ATOM_DEVICE_DFP1_SUPPORT)) {
-			gpio = radeon_lookup_gpio(rdev, 7);
-			*hpd = radeon_atom_get_hpd_info_from_gpio(rdev, &gpio);
+			return false;
 		}
 	}
 
author
#244 lore raw

PATCH 244/272 drm/radeon/kms: make the mac rv630 quirk generic

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Alex Deucher <[email protected]>

commit be23da8ad219650517cbbb7acbeaeb235667113a upstream.

Seems some other boards do this as well.

---
 drivers/gpu/drm/radeon/radeon_atombios.c |   14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)
drivers/gpu/drm/radeon/radeon_atombios.c +5 -9
@@ -387,15 +387,11 @@ static bool radeon_atom_apply_quirks(str
 			*line_mux = 0x90;
 	}
 
-	/* mac rv630 */
-	if ((dev->pdev->device == 0x9588) &&
-	    (dev->pdev->subsystem_vendor == 0x106b) &&
-	    (dev->pdev->subsystem_device == 0x00a6)) {
-		if ((supported_device == ATOM_DEVICE_TV1_SUPPORT) &&
-		    (*connector_type == DRM_MODE_CONNECTOR_DVII)) {
-			*connector_type = DRM_MODE_CONNECTOR_9PinDIN;
-			*line_mux = CONNECTOR_7PIN_DIN_ENUM_ID1;
-		}
+	/* mac rv630, rv730, others */
+	if ((supported_device == ATOM_DEVICE_TV1_SUPPORT) &&
+	    (*connector_type == DRM_MODE_CONNECTOR_DVII)) {
+		*connector_type = DRM_MODE_CONNECTOR_9PinDIN;
+		*line_mux = CONNECTOR_7PIN_DIN_ENUM_ID1;
 	}
 
 	/* ASUS HD 3600 XT board lists the DVI port as HDMI */
author
#245 lore raw

PATCH 245/272 radeon/kms: fix dp displayport mode validation

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Jerome Glisse <[email protected]>

commit 6bba2e116808ca12e30c8d88dfedabf8b8d67390 upstream.

Check if there is a big enough dp clock & enough dp lane to drive the video mode provided.

---
 drivers/gpu/drm/radeon/atombios_dp.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/radeon/atombios_dp.c +2 -2
@@ -187,9 +187,9 @@ static int dp_link_clock_for_mode_clock(
 int dp_mode_valid(u8 dpcd[DP_DPCD_SIZE], int mode_clock)
 {
 	int lanes = dp_lanes_for_mode_clock(dpcd, mode_clock);
-	int bw = dp_lanes_for_mode_clock(dpcd, mode_clock);
+	int dp_clock = dp_link_clock_for_mode_clock(dpcd, mode_clock);
 
-	if ((lanes == 0) || (bw == 0))
+	if ((lanes == 0) || (dp_clock == 0))
 		return MODE_CLOCK_HIGH;
 
 	return MODE_OK;
author
#246 lore raw

PATCH 246/272 drm/radeon/kms: re-emit full context state for evergreen blits

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Alex Deucher <[email protected]>

commit 1e644d6dce366a7bae22484f60133b61ba322911 upstream.

clear state doesn't seem to work properly in some cases

Fixes hangs in heavy 3D on some evergreen cards reported on IRC.

May fix:
https://bugs.freedesktop.org/show_bug.cgi?id=33381
possibly others.

---
 drivers/gpu/drm/radeon/evergreen_blit_kms.c |   39 +++++++++++++++++++++++-----
 1 file changed, 33 insertions(+), 6 deletions(-)
drivers/gpu/drm/radeon/evergreen_blit_kms.c +33 -6
@@ -230,7 +230,7 @@ draw_auto(struct radeon_device *rdev)
 
 }
 
-/* emits 30 */
+/* emits 34 */
 static void
 set_default_state(struct radeon_device *rdev)
 {
@@ -243,6 +243,8 @@ set_default_state(struct radeon_device *
 	int num_hs_threads, num_ls_threads;
 	int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries;
 	int num_hs_stack_entries, num_ls_stack_entries;
+	u64 gpu_addr;
+	int dwords;
 
 	switch (rdev->family) {
 	case CHIP_CEDAR:
@@ -409,6 +411,14 @@ set_default_state(struct radeon_device *
 	radeon_ring_write(rdev, 0x00000000);
 	radeon_ring_write(rdev, 0x00000000);
 
+	/* emit an IB pointing at default state */
+	dwords = ALIGN(rdev->r600_blit.state_len, 0x10);
+	gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset;
+	radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
+	radeon_ring_write(rdev, gpu_addr & 0xFFFFFFFC);
+	radeon_ring_write(rdev, upper_32_bits(gpu_addr) & 0xFF);
+	radeon_ring_write(rdev, dwords);
+
 }
 
 static inline uint32_t i2f(uint32_t input)
@@ -439,8 +449,10 @@ static inline uint32_t i2f(uint32_t inpu
 int evergreen_blit_init(struct radeon_device *rdev)
 {
 	u32 obj_size;
-	int r;
+	int r, dwords;
 	void *ptr;
+	u32 packet2s[16];
+	int num_packet2s = 0;
 
 	/* pin copy shader into vram if already initialized */
 	if (rdev->r600_blit.shader_obj)
@@ -448,8 +460,17 @@ int evergreen_blit_init(struct radeon_de
 
 	mutex_init(&rdev->r600_blit.mutex);
 	rdev->r600_blit.state_offset = 0;
-	rdev->r600_blit.state_len = 0;
-	obj_size = 0;
+
+	rdev->r600_blit.state_len = evergreen_default_size;
+
+	dwords = rdev->r600_blit.state_len;
+	while (dwords & 0xf) {
+		packet2s[num_packet2s++] = PACKET2(0);
+		dwords++;
+	}
+
+	obj_size = dwords * 4;
+	obj_size = ALIGN(obj_size, 256);
 
 	rdev->r600_blit.vs_offset = obj_size;
 	obj_size += evergreen_vs_size * 4;
@@ -479,6 +500,12 @@ int evergreen_blit_init(struct radeon_de
 		return r;
 	}
 
+	memcpy_toio(ptr + rdev->r600_blit.state_offset,
+		    evergreen_default_state, rdev->r600_blit.state_len * 4);
+
+	if (num_packet2s)
+		memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),
+			    packet2s, num_packet2s * 4);
 	memcpy(ptr + rdev->r600_blit.vs_offset, evergreen_vs, evergreen_vs_size * 4);
 	memcpy(ptr + rdev->r600_blit.ps_offset, evergreen_ps, evergreen_ps_size * 4);
 	radeon_bo_kunmap(rdev->r600_blit.shader_obj);
@@ -564,7 +591,7 @@ int evergreen_blit_prepare_copy(struct r
 	/* calculate number of loops correctly */
 	ring_size = num_loops * dwords_per_loop;
 	/* set default  + shaders */
-	ring_size += 46; /* shaders + def state */
+	ring_size += 50; /* shaders + def state */
 	ring_size += 10; /* fence emit for VB IB */
 	ring_size += 5; /* done copy */
 	ring_size += 10; /* fence emit for done copy */
@@ -572,7 +599,7 @@ int evergreen_blit_prepare_copy(struct r
 	if (r)
 		return r;
 
-	set_default_state(rdev); /* 30 */
+	set_default_state(rdev); /* 34 */
 	set_shaders(rdev); /* 16 */
 	return 0;
 }
author
#247 lore raw

PATCH 247/272 drm/radeon/kms: switch back to min->max pll post divider iteration

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Alex Deucher <[email protected]>

commit a6f9761743bf35b052180f4a8bdae4d2cc0465f6 upstream.

Seems more reliable. Fixes:
https://bugzilla.kernel.org/show_bug.cgi?id=26552

---
 drivers/gpu/drm/radeon/radeon_display.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/radeon/radeon_display.c +1 -1
@@ -517,7 +517,7 @@ void radeon_compute_pll(struct radeon_pl
 		max_fractional_feed_div = pll->max_frac_feedback_div;
 	}
 
-	for (post_div = max_post_div; post_div >= min_post_div; --post_div) {
+	for (post_div = min_post_div; post_div <= max_post_div; ++post_div) {
 		uint32_t ref_div;
 
 		if ((pll->flags & RADEON_PLL_NO_ODD_POST_DIV) && (post_div & 1))
author
#248 lore raw

PATCH 248/272 drm/radeon/kms: add pll debugging output

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Alex Deucher <[email protected]>

commit 51d4bf840a27fe02c883ddc6d9708af056773769 upstream.

---
 drivers/gpu/drm/radeon/radeon_display.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/gpu/drm/radeon/radeon_display.c +4 -0
@@ -633,6 +633,10 @@ void radeon_compute_pll(struct radeon_pl
 	*frac_fb_div_p = best_frac_feedback_div;
 	*ref_div_p = best_ref_div;
 	*post_div_p = best_post_div;
+	DRM_DEBUG_KMS("%d %d, pll dividers - fb: %d.%d ref: %d, post %d\n",
+		      freq, best_freq / 1000, best_feedback_div, best_frac_feedback_div,
+		      best_ref_div, best_post_div);
+
 }
 
 static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb)
author
#249 lore raw

PATCH 249/272 drm/radeon/kms: add new pll algo for avivo asics

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Alex Deucher <[email protected]>

commit f523f74eac1897b13c05c88ce6e5de0a7c34578b upstream.

Based on the vbios code. This should hopefully fix the pll problems on a number of avivo asics once it's enabled.

---
 drivers/gpu/drm/radeon/atombios_crtc.c      |    4 
 drivers/gpu/drm/radeon/radeon_display.c     |  123 ++++++++++++++++++++++++++--
 drivers/gpu/drm/radeon/radeon_legacy_crtc.c |    6 -
 drivers/gpu/drm/radeon/radeon_mode.h        |   23 +++--
 4 files changed, 137 insertions(+), 19 deletions(-)
drivers/gpu/drm/radeon/atombios_crtc.c +2 -2
@@ -915,8 +915,8 @@ static void atombios_crtc_set_pll(struct
 	/* adjust pixel clock as needed */
 	adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss);
 
-	radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
-			   &ref_div, &post_div);
+	radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
+				  &ref_div, &post_div);
 
 	atombios_crtc_program_ss(crtc, ATOM_DISABLE, radeon_crtc->pll_id, &ss);
 
drivers/gpu/drm/radeon/radeon_display.c +116 -7

135 lines not on this page · raw message

drivers/gpu/drm/radeon/radeon_legacy_crtc.c +3 -3
@@ -778,9 +778,9 @@ static void radeon_set_pll(struct drm_cr
 	DRM_DEBUG_KMS("\n");
 
 	if (!use_bios_divs) {
-		radeon_compute_pll(pll, mode->clock,
-				   &freq, &feedback_div, &frac_fb_div,
-				   &reference_div, &post_divider);
+		radeon_compute_pll_legacy(pll, mode->clock,
+					  &freq, &feedback_div, &frac_fb_div,
+					  &reference_div, &post_divider);
 
 		for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
 			if (post_div->divider == post_divider)
drivers/gpu/drm/radeon/radeon_mode.h +16 -7
@@ -149,6 +149,7 @@ struct radeon_tmds_pll {
 #define RADEON_PLL_PREFER_CLOSEST_LOWER (1 << 11)
 #define RADEON_PLL_USE_POST_DIV         (1 << 12)
 #define RADEON_PLL_IS_LCD               (1 << 13)
+#define RADEON_PLL_PREFER_MINM_OVER_MAXP (1 << 14)
 
 struct radeon_pll {
 	/* reference frequency */
@@ -510,13 +511,21 @@ extern bool radeon_atombios_get_asic_ss_
 					     struct radeon_atom_ss *ss,
 					     int id, u32 clock);
 
-extern void radeon_compute_pll(struct radeon_pll *pll,
-			       uint64_t freq,
-			       uint32_t *dot_clock_p,
-			       uint32_t *fb_div_p,
-			       uint32_t *frac_fb_div_p,
-			       uint32_t *ref_div_p,
-			       uint32_t *post_div_p);
+extern void radeon_compute_pll_legacy(struct radeon_pll *pll,
+				      uint64_t freq,
+				      uint32_t *dot_clock_p,
+				      uint32_t *fb_div_p,
+				      uint32_t *frac_fb_div_p,
+				      uint32_t *ref_div_p,
+				      uint32_t *post_div_p);
+
+extern void radeon_compute_pll_avivo(struct radeon_pll *pll,
+				     u32 freq,
+				     u32 *dot_clock_p,
+				     u32 *fb_div_p,
+				     u32 *frac_fb_div_p,
+				     u32 *ref_div_p,
+				     u32 *post_div_p);
 
 extern void radeon_setup_encoder_clones(struct drm_device *dev);
 
author
#250 lore raw

PATCH 250/272 drm/radeon/kms: Enable new pll calculation for avivo+ asics

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Alex Deucher <[email protected]>

commit 619efb105924d8cafa0c1dd9389e9ab506f5425d upstream.

New algo is used for r5xx+ and legacy is used for r1xx-r4xx, rv515.

I've tested on all relevant GPUs and monitors that I have access to and have found no problems.

Fixes:
https://bugzilla.kernel.org/show_bug.cgi?id=26562
https://bugzilla.kernel.org/show_bug.cgi?id=26552
May fix:
https://bugs.freedesktop.org/show_bug.cgi?id=32556

---
 drivers/gpu/drm/radeon/atombios_crtc.c   |   18 ++++++++++++++++--
 drivers/gpu/drm/radeon/radeon_atombios.c |   10 ----------
 drivers/gpu/drm/radeon/radeon_display.c  |    3 +++
 3 files changed, 19 insertions(+), 12 deletions(-)
drivers/gpu/drm/radeon/atombios_crtc.c +16 -2
@@ -531,6 +531,7 @@ static u32 atombios_adjust_pll(struct dr
 					dp_clock = dig_connector->dp_clock;
 				}
 			}
+/* this might work properly with the new pll algo */
 #if 0 /* doesn't work properly on some laptops */
 			/* use recommended ref_div for ss */
 			if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
@@ -548,6 +549,11 @@ static u32 atombios_adjust_pll(struct dr
 					adjusted_clock = mode->clock * 2;
 				if (radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT))
 					pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
+				/* rv515 needs more testing with this option */
+				if (rdev->family != CHIP_RV515) {
+					if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
+						pll->flags |= RADEON_PLL_IS_LCD;
+				}
 			} else {
 				if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
 					pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
@@ -915,8 +921,16 @@ static void atombios_crtc_set_pll(struct
 	/* adjust pixel clock as needed */
 	adjusted_clock = atombios_adjust_pll(crtc, mode, pll, ss_enabled, &ss);
 
-	radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
-				  &ref_div, &post_div);
+	/* rv515 seems happier with the old algo */
+	if (rdev->family == CHIP_RV515)
+		radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
+					  &ref_div, &post_div);
+	else if (ASIC_IS_AVIVO(rdev))
+		radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
+					 &ref_div, &post_div);
+	else
+		radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
+					  &ref_div, &post_div);
 
 	atombios_crtc_program_ss(crtc, ATOM_DISABLE, radeon_crtc->pll_id, &ss);
 
drivers/gpu/drm/radeon/radeon_atombios.c +0 -10
@@ -1136,16 +1136,6 @@ bool radeon_atom_get_clock_info(struct d
 				p1pll->pll_out_min = 64800;
 			else
 				p1pll->pll_out_min = 20000;
-		} else if (p1pll->pll_out_min > 64800) {
-			/* Limiting the pll output range is a good thing generally as
-			 * it limits the number of possible pll combinations for a given
-			 * frequency presumably to the ones that work best on each card.
-			 * However, certain duallink DVI monitors seem to like
-			 * pll combinations that would be limited by this at least on
-			 * pre-DCE 3.0 r6xx hardware.  This might need to be adjusted per
-			 * family.
-			 */
-			p1pll->pll_out_min = 64800;
 		}
 
 		p1pll->pll_in_min =
drivers/gpu/drm/radeon/radeon_display.c +3 -0
@@ -603,6 +603,9 @@ void radeon_compute_pll_legacy(struct ra
 		pll_out_max = pll->pll_out_max;
 	}
 
+	if (pll_out_min > 64800)
+		pll_out_min = 64800;
+
 	if (pll->flags & RADEON_PLL_USE_REF_DIV)
 		min_ref_div = max_ref_div = pll->reference_div;
 	else {
author
#251 lore raw

PATCH 251/272 drm/radeon: remove 0x4243 pci id

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Alex Deucher <[email protected]>

commit 63a507800c8aca5a1891d598ae13f829346e8e39 upstream.

0x4243 is a PCI bridge, not a GPU.

Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=33815

---
 include/drm/drm_pciids.h |    1 -
 1 file changed, 1 deletion(-)
include/drm/drm_pciids.h +0 -1
@@ -28,7 +28,6 @@
 	{0x1002, 0x4156, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
 	{0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP}, \
 	{0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
-	{0x1002, 0x4243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
 	{0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
 	{0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
 	{0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
author
#252 lore raw

PATCH 252/272 drm/radeon/kms/evergreen: always set certain VGT regs at CP init

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Alex Deucher <[email protected]>

commit 18ff84da29b3f0c073e0ce6e341663cc6bcb0ab7 upstream.

These should be handled by the clear_state setup, but set them directly as well just to be sure.

---
 drivers/gpu/drm/radeon/evergreen.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/radeon/evergreen.c +6 -1
@@ -1135,7 +1135,7 @@ static int evergreen_cp_start(struct rad
 	cp_me = 0xff;
 	WREG32(CP_ME_CNTL, cp_me);
 
-	r = radeon_ring_lock(rdev, evergreen_default_size + 15);
+	r = radeon_ring_lock(rdev, evergreen_default_size + 19);
 	if (r) {
 		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
 		return r;
@@ -1168,6 +1168,11 @@ static int evergreen_cp_start(struct rad
 	radeon_ring_write(rdev, 0xffffffff);
 	radeon_ring_write(rdev, 0xffffffff);
 
+	radeon_ring_write(rdev, 0xc0026900);
+	radeon_ring_write(rdev, 0x00000316);
+	radeon_ring_write(rdev, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
+	radeon_ring_write(rdev, 0x00000010); /*  */
+
 	radeon_ring_unlock_commit(rdev);
 
 	return 0;
author
#253 lore raw

PATCH 253/272 drm/radeon/kms: fix s/r issues with bios scratch regs

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Alex Deucher <[email protected]>

commit 87364760de5d631390c478fcbac8db1b926e0adf upstream.

The accelerate mode bit gets checked by certain atom command tables to set up some register state. It needs to be clear when setting modes and set when not.

Fixes:
https://bugzilla.kernel.org/show_bug.cgi?id=26942

---
 drivers/gpu/drm/radeon/radeon_atombios.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/gpu/drm/radeon/radeon_atombios.c +6 -3
@@ -2357,7 +2357,7 @@ void radeon_atom_initialize_bios_scratch
 	bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE;
 
 	/* tell the bios not to handle mode switching */
-	bios_6_scratch |= (ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH | ATOM_S6_ACC_MODE);
+	bios_6_scratch |= ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH;
 
 	if (rdev->family >= CHIP_R600) {
 		WREG32(R600_BIOS_2_SCRATCH, bios_2_scratch);
@@ -2408,10 +2408,13 @@ void radeon_atom_output_lock(struct drm_
 	else
 		bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
 
-	if (lock)
+	if (lock) {
 		bios_6_scratch |= ATOM_S6_CRITICAL_STATE;
-	else
+		bios_6_scratch &= ~ATOM_S6_ACC_MODE;
+	} else {
 		bios_6_scratch &= ~ATOM_S6_CRITICAL_STATE;
+		bios_6_scratch |= ATOM_S6_ACC_MODE;
+	}
 
 	if (rdev->family >= CHIP_R600)
 		WREG32(R600_BIOS_6_SCRATCH, bios_6_scratch);
author
#254 lore raw

PATCH 254/272 drm: Restore the old_fb upon modeset failure

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Chris Wilson <[email protected]>

commit 0ba41e449fd0f45f5b29c1009020ab1b298bedda upstream.

... or else we may end up disabling the wrong framebuffer, leading to an OOPS, e.g:

[ 6033.229012] kernel BUG at drivers/gpu/drm/i915/i915_gem.c:3271!
[ 6033.229012] invalid opcode: 0000 [#1] SMP
[ 6033.229012] last sysfs file:
/sys/devices/virtual/backlight/acpi_video0/uevent
[ 6033.229012] Modules linked in: sunrpc cpufreq_ondemand acpi_cpufreq

mperf snd_hda_codec_analog snd_hda_intel snd_hda_codec snd_hwdep snd_seq snd_seq_device snd_pcm snd_timer thinkpad_acpi ppdev snd r852 sm_common iTCO_wdt uvcvideo i2c_i801 iTCO_vendor_support microcode wmi nand videodev nand_ids nand_ecc snd_page_alloc parport_pc parport mtd soundcore joydev v4l1_compat pcspkr uinput ipv6 sdhci_pci sdhci mmc_core yenta_socket i915 drm_kms_helper drm i2c_algo_bit i2c_core video output [last unloaded: scsi_wait_scan]

[ 6033.229012]
[ 6033.229012] Pid: 4834, comm: Xorg Not tainted 2.6.37-rc8+ #25 7661BL5/7661BL5
[ 6033.229012] EIP: 0060:[<f86fda5e>] EFLAGS: 00013246 CPU: 0
[ 6033.229012] EIP is at i915_gem_object_unpin+0x23/0x76 [i915]
[ 6033.229012] EAX: f68a4000 EBX: f6831f00 ECX: 000600fa EDX: f68a8000
[ 6033.229012] ESI: f68a4014 EDI: f68a42b8 EBP: f2169c44 ESP: f2169c3c
[ 6033.229012]  DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
[ 6033.229012] Process Xorg (pid: 4834, ti=f2168000 task=f21c8000 task.ti=f2168000)
[ 6033.229012] Stack:
[ 6033.229012]  f3a84800 f68a4014 f2169c54 f87045d8 f3a84800 f872d9a8 f2169c68 f7fd8091
[ 6033.229012]  f3b952a4 00000000 f68a414c f2169cf0 f7fd9377 00000000 00000000 f7fd98b0
[ 6033.229012]  f7fd9f4e 0000000f f7f328a0 00000000 00000000 00000000 f2169ca4 f68a414c
[ 6033.229012] Call Trace:
[ 6033.229012]  [<f87045d8>] ? intel_crtc_disable+0x36/0x41 [i915]
[ 6033.229012]  [<f7fd8091>] ?  drm_helper_disable_unused_functions+0xcd/0xf9 [drm_kms_helper]
[ 6033.229012]  [<f7fd9377>] ? drm_crtc_helper_set_config+0x62a/0x7f7 [drm_kms_helper]
[ 6033.229012]  [<c04daa10>] ? __slab_free+0x1b/0xa4
[ 6033.229012]  [<f7fd7e62>] ? drm_fb_helper_initial_config+0x466/0x497 [drm_kms_helper]
[ 6033.229012]  [<f7fd7ea3>] ? drm_fb_helper_restore+0x10/0x2a [drm_kms_helper]
[ 6033.229012]  [<f86f2577>] ? i915_driver_lastclose+0x2a/0x57 [i915]
[ 6033.229012]  [<f7f1989f>] ? drm_lastclose+0x45/0x23e [drm]
[ 6033.229012]  [<f7f1a0b4>] ? drm_release+0x462/0x4d7 [drm]
---
 drivers/gpu/drm/drm_crtc_helper.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/gpu/drm/drm_crtc_helper.c +4 -1
@@ -650,6 +650,7 @@ int drm_crtc_helper_set_config(struct dr
 						      old_fb)) {
 				DRM_ERROR("failed to set mode on [CRTC:%d]\n",
 					  set->crtc->base.id);
+				set->crtc->fb = old_fb;
 				ret = -EINVAL;
 				goto fail;
 			}
@@ -664,8 +665,10 @@ int drm_crtc_helper_set_config(struct dr
 			set->crtc->fb = set->fb;
 		ret = crtc_funcs->mode_set_base(set->crtc,
 						set->x, set->y, old_fb);
-		if (ret != 0)
+		if (ret != 0) {
+			set->crtc->fb = old_fb;
 			goto fail;
+		}
 	}
 	DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
 	for (i = 0; i < set->num_connectors; i++) {
author
#255 lore raw

PATCH 255/272 drm/i915: check eDP encoder correctly when setting modes

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Jesse Barnes <[email protected]>

commit 858bc21f0637c407601a05626854ae58b242f75d upstream.

We were using a stale pointer in the check which caused us to use CPU attached DP params when we should have been using PCH attached params.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=31988

---
 drivers/gpu/drm/i915/intel_display.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/i915/intel_display.c +1 -1
@@ -3714,7 +3714,7 @@ static int intel_crtc_mode_set(struct dr
 		int lane = 0, link_bw, bpp;
 		/* CPU eDP doesn't require FDI link, so just set DP M/N
 		   according to current link config */
-		if (has_edp_encoder && !intel_encoder_is_pch_edp(&encoder->base)) {
+		if (has_edp_encoder && !intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
 			target_clock = mode->clock;
 			intel_edp_link_config(has_edp_encoder,
 					      &lane, &link_bw);
author
#256 lore raw

PATCH 256/272 drm/i915/sdvo: Defer detection of output capabilities until probing

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Chris Wilson <[email protected]>

commit 97aaf910731b03b27b1c4c8a58006a1dc99dcd9a upstream.

Alex Fiestas reported an issue with his HDMI connector being misdetected as DVI unless he had something connected upon boot. By moving the decision as to whether to use HDMI or DVI encoding for the HDMI capable output until we probe the monitor means that we should avoid sending a HDMI signal to a DVI monitor and also correctly detect hardware like Alex's.

However, to really determine what connector is soldered onto the wire we need to inspect the VBT sdvo child devices - but can we trust it?

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=32828

---
 drivers/gpu/drm/i915/intel_sdvo.c |   33 +++++++++++----------------------
 1 file changed, 11 insertions(+), 22 deletions(-)
drivers/gpu/drm/i915/intel_sdvo.c +11 -22
@@ -1024,9 +1024,13 @@ static void intel_sdvo_mode_set(struct d
 	if (!intel_sdvo_set_target_input(intel_sdvo))
 		return;
 
-	if (intel_sdvo->has_hdmi_monitor &&
-	    !intel_sdvo_set_avi_infoframe(intel_sdvo))
-		return;
+	if (intel_sdvo->has_hdmi_monitor) {
+		intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI);
+		intel_sdvo_set_colorimetry(intel_sdvo,
+					   SDVO_COLORIMETRY_RGB256);
+		intel_sdvo_set_avi_infoframe(intel_sdvo);
+	} else
+		intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_DVI);
 
 	if (intel_sdvo->is_tv &&
 	    !intel_sdvo_set_tv_format(intel_sdvo))
@@ -1395,6 +1399,9 @@ intel_sdvo_detect(struct drm_connector *
 
 	intel_sdvo->attached_output = response;
 
+	intel_sdvo->has_hdmi_monitor = false;
+	intel_sdvo->has_hdmi_audio = false;
+
 	if ((intel_sdvo_connector->output_flag & response) == 0)
 		ret = connector_status_disconnected;
 	else if (response & SDVO_TMDS_MASK)
@@ -1919,20 +1926,7 @@ intel_sdvo_select_i2c_bus(struct drm_i91
 static bool
 intel_sdvo_is_hdmi_connector(struct intel_sdvo *intel_sdvo, int device)
 {
-	int is_hdmi;
-
-	if (!intel_sdvo_check_supp_encode(intel_sdvo))
-		return false;
-
-	if (!intel_sdvo_set_target_output(intel_sdvo,
-					  device == 0 ? SDVO_OUTPUT_TMDS0 : SDVO_OUTPUT_TMDS1))
-		return false;
-
-	is_hdmi = 0;
-	if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ENCODE, &is_hdmi, 1))
-		return false;
-
-	return !!is_hdmi;
+	return intel_sdvo_check_supp_encode(intel_sdvo);
 }
 
 static u8
@@ -2034,12 +2028,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *i
 	connector->connector_type = DRM_MODE_CONNECTOR_DVID;
 
 	if (intel_sdvo_is_hdmi_connector(intel_sdvo, device)) {
-		/* enable hdmi encoding mode if supported */
-		intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI);
-		intel_sdvo_set_colorimetry(intel_sdvo,
-					   SDVO_COLORIMETRY_RGB256);
 		connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
-
 		intel_sdvo->is_hdmi = true;
 	}
 	intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
author
#257 lore raw

PATCH 257/272 drm/i915/crt: Check for a analog monitor in case of DVI-I

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: =?UTF-8?q?David=20M=C3=BCller?= <[email protected]>

commit f5afcd3dd0dca7fe869311c51da54d5a889191ba upstream.

Since Linux 2.6.36 the digital output on my system (855GME + DVI-I) is not working any longer. The analog output is always activated regardless of the type of monitor attached.

The culprit seems to be intel_crt_detect_ddc(), which returns true as soon as an ACK from the EDID device is received. Obviously this approach does not work with DVI-I where the analog and digital outputs share a common DDC bus.

In a similar manner to the shared DDC wire, ala the "Mac Mini Hack", we need an additional check to make sure that there really is an analog device attached to the DDC.

---
 drivers/gpu/drm/i915/intel_crt.c |   30 +++++++++++++++++++++++++-----
 1 file changed, 25 insertions(+), 5 deletions(-)
drivers/gpu/drm/i915/intel_crt.c +25 -5
@@ -30,6 +30,7 @@
 #include "drm.h"
 #include "drm_crtc.h"
 #include "drm_crtc_helper.h"
+#include "drm_edid.h"
 #include "intel_drv.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
@@ -287,8 +288,9 @@ static bool intel_crt_ddc_probe(struct d
 	return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 1) == 1;
 }
 
-static bool intel_crt_detect_ddc(struct intel_crt *crt)
+static bool intel_crt_detect_ddc(struct drm_connector *connector)
 {
+	struct intel_crt *crt = intel_attached_crt(connector);
 	struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private;
 
 	/* CRT should always be at 0, but check anyway */
@@ -301,8 +303,26 @@ static bool intel_crt_detect_ddc(struct
 	}
 
 	if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) {
-		DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n");
-		return true;
+		struct edid *edid;
+		bool is_digital = false;
+
+		edid = drm_get_edid(connector,
+			&dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter);
+		/*
+		 * This may be a DVI-I connector with a shared DDC
+		 * link between analog and digital outputs, so we
+		 * have to check the EDID input spec of the attached device.
+		 */
+		if (edid != NULL) {
+			is_digital = edid->input & DRM_EDID_INPUT_DIGITAL;
+			connector->display_info.raw_edid = NULL;
+			kfree(edid);
+		}
+
+		if (!is_digital) {
+			DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n");
+			return true;
+		}
 	}
 
 	return false;
@@ -458,7 +478,7 @@ intel_crt_detect(struct drm_connector *c
 		}
 	}
 
-	if (intel_crt_detect_ddc(crt))
+	if (intel_crt_detect_ddc(connector))
 		return connector_status_connected;
 
 	if (!force)
@@ -472,7 +492,7 @@ intel_crt_detect(struct drm_connector *c
 		crtc = intel_get_load_detect_pipe(&crt->base, connector,
 						  NULL, &dpms_mode);
 		if (crtc) {
-			if (intel_crt_detect_ddc(crt))
+			if (intel_crt_detect_ddc(connector))
 				status = connector_status_connected;
 			else
 				status = intel_crt_load_detect(crtc, crt);
author
#258 lore raw

PATCH 258/272 drm/i915: fix calculation of eDP signal levels on Sandybridge

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Yuanhan Liu <[email protected]>

commit 3c5a62b5226ca5db993660281e9c2a7275d9fb02 upstream.

Some voltage swing/pre-emphasis level use the same value on eDP Sandybridge, like 400mv_0db and 600mv_0db are with the same value of (0x0 << 22). So, fix them, and point out the value if it isn't a supported voltage swing/pre-emphasis level.

---
 drivers/gpu/drm/i915/i915_reg.h |    9 +++++----
 drivers/gpu/drm/i915/intel_dp.c |   23 ++++++++++++++++-------
 2 files changed, 21 insertions(+), 11 deletions(-)
drivers/gpu/drm/i915/i915_reg.h +5 -4
@@ -3057,10 +3057,11 @@
 #define  EDP_LINK_TRAIN_600MV_3_5DB_SNB_A	(0x01<<22)
 #define  EDP_LINK_TRAIN_800MV_0DB_SNB_A		(0x0<<22)
 /* SNB B-stepping */
-#define  EDP_LINK_TRAIN_400MV_0DB_SNB_B		(0x0<<22)
-#define  EDP_LINK_TRAIN_400MV_6DB_SNB_B		(0x3a<<22)
-#define  EDP_LINK_TRAIN_600MV_3_5DB_SNB_B	(0x39<<22)
-#define  EDP_LINK_TRAIN_800MV_0DB_SNB_B		(0x38<<22)
+#define  EDP_LINK_TRAIN_400_600MV_0DB_SNB_B	(0x0<<22)
+#define  EDP_LINK_TRAIN_400MV_3_5DB_SNB_B	(0x1<<22)
+#define  EDP_LINK_TRAIN_400_600MV_6DB_SNB_B	(0x3a<<22)
+#define  EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B	(0x39<<22)
+#define  EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B	(0x38<<22)
 #define  EDP_LINK_TRAIN_VOL_EMP_MASK_SNB	(0x3f<<22)
 
 #endif /* _I915_REG_H_ */
drivers/gpu/drm/i915/intel_dp.c +16 -7
@@ -1153,18 +1153,27 @@ intel_dp_signal_levels(uint8_t train_set
 static uint32_t
 intel_gen6_edp_signal_levels(uint8_t train_set)
 {
-	switch (train_set & (DP_TRAIN_VOLTAGE_SWING_MASK|DP_TRAIN_PRE_EMPHASIS_MASK)) {
+	int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK |
+					 DP_TRAIN_PRE_EMPHASIS_MASK);
+	switch (signal_levels) {
 	case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0:
-		return EDP_LINK_TRAIN_400MV_0DB_SNB_B;
+	case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_0:
+		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
+	case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_3_5:
+		return EDP_LINK_TRAIN_400MV_3_5DB_SNB_B;
 	case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6:
-		return EDP_LINK_TRAIN_400MV_6DB_SNB_B;
+	case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_6:
+		return EDP_LINK_TRAIN_400_600MV_6DB_SNB_B;
 	case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5:
-		return EDP_LINK_TRAIN_600MV_3_5DB_SNB_B;
+	case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_3_5:
+		return EDP_LINK_TRAIN_600_800MV_3_5DB_SNB_B;
 	case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0:
-		return EDP_LINK_TRAIN_800MV_0DB_SNB_B;
+	case DP_TRAIN_VOLTAGE_SWING_1200 | DP_TRAIN_PRE_EMPHASIS_0:
+		return EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B;
 	default:
-		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level\n");
-		return EDP_LINK_TRAIN_400MV_0DB_SNB_B;
+		DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:"
+			      "0x%x\n", signal_levels);
+		return EDP_LINK_TRAIN_400_600MV_0DB_SNB_B;
 	}
 }
 
author
#259 lore raw

PATCH 259/272 drm/i915/panel: Only record the backlight level when it is enabled

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Chris Wilson <[email protected]>

commit 47356eb67285014527a5ab87543ba1fae3d1e10a upstream.

By tracking the current status of the backlight we can prevent recording the value of the current backlight when we have disabled it. And so prevent restoring it to 'off' after an unbalanced sequence of intel_lvds_disable/enable.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=22672

---
 drivers/gpu/drm/i915/i915_drv.h      |    1 +
 drivers/gpu/drm/i915/intel_display.c |    2 ++
 drivers/gpu/drm/i915/intel_drv.h     |    3 +++
 drivers/gpu/drm/i915/intel_lvds.c    |   10 ++--------
 drivers/gpu/drm/i915/intel_panel.c   |   31 +++++++++++++++++++++++++++++++
 5 files changed, 39 insertions(+), 8 deletions(-)
drivers/gpu/drm/i915/i915_drv.h +1 -0
@@ -329,6 +329,7 @@ typedef struct drm_i915_private {
 
 	/* LVDS info */
 	int backlight_level;  /* restore backlight to this value */
+	bool backlight_enabled;
 	struct drm_display_mode *panel_fixed_mode;
 	struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
 	struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
drivers/gpu/drm/i915/intel_display.c +2 -0
@@ -5498,6 +5498,8 @@ static void intel_setup_outputs(struct d
 		encoder->base.possible_clones =
 			intel_encoder_clones(dev, encoder->clone_mask);
 	}
+
+	intel_panel_setup_backlight(dev);
 }
 
 static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
drivers/gpu/drm/i915/intel_drv.h +3 -0
@@ -256,6 +256,9 @@ extern void intel_pch_panel_fitting(stru
 extern u32 intel_panel_get_max_backlight(struct drm_device *dev);
 extern u32 intel_panel_get_backlight(struct drm_device *dev);
 extern void intel_panel_set_backlight(struct drm_device *dev, u32 level);
+extern void intel_panel_setup_backlight(struct drm_device *dev);
+extern void intel_panel_enable_backlight(struct drm_device *dev);
+extern void intel_panel_disable_backlight(struct drm_device *dev);
 
 extern void intel_crtc_load_lut(struct drm_crtc *crtc);
 extern void intel_encoder_prepare (struct drm_encoder *encoder);
drivers/gpu/drm/i915/intel_lvds.c +2 -8
@@ -106,7 +106,7 @@ static void intel_lvds_enable(struct int
 	I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
 	POSTING_READ(lvds_reg);
 
-	intel_panel_set_backlight(dev, dev_priv->backlight_level);
+	intel_panel_enable_backlight(dev);
 }
 
 static void intel_lvds_disable(struct intel_lvds *intel_lvds)
@@ -123,8 +123,7 @@ static void intel_lvds_disable(struct in
 		lvds_reg = LVDS;
 	}
 
-	dev_priv->backlight_level = intel_panel_get_backlight(dev);
-	intel_panel_set_backlight(dev, 0);
+	intel_panel_disable_backlight(dev);
 
 	I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON);
 
@@ -395,8 +394,6 @@ static void intel_lvds_prepare(struct dr
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
 
-	dev_priv->backlight_level = intel_panel_get_backlight(dev);
-
 	/* We try to do the minimum that is necessary in order to unlock
 	 * the registers for mode setting.
 	 *
@@ -427,9 +424,6 @@ static void intel_lvds_commit(struct drm
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
 
-	if (dev_priv->backlight_level == 0)
-		dev_priv->backlight_level = intel_panel_get_max_backlight(dev);
-
 	/* Undo any unlocking done in prepare to prevent accidental
 	 * adjustment of the registers.
 	 */
drivers/gpu/drm/i915/intel_panel.c +31 -0
@@ -218,3 +218,34 @@ void intel_panel_set_backlight(struct dr
 		tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK;
 	I915_WRITE(BLC_PWM_CTL, tmp | level);
 }
+
+void intel_panel_disable_backlight(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->backlight_enabled) {
+		dev_priv->backlight_level = intel_panel_get_backlight(dev);
+		dev_priv->backlight_enabled = false;
+	}
+
+	intel_panel_set_backlight(dev, 0);
+}
+
+void intel_panel_enable_backlight(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->backlight_level == 0)
+		dev_priv->backlight_level = intel_panel_get_max_backlight(dev);
+
+	intel_panel_set_backlight(dev, dev_priv->backlight_level);
+	dev_priv->backlight_enabled = true;
+}
+
+void intel_panel_setup_backlight(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	dev_priv->backlight_level = intel_panel_get_max_backlight(dev);
+	dev_priv->backlight_enabled = dev_priv->backlight_level != 0;
+}
author
#260 lore raw

PATCH 260/272 drm/i915/panel: The backlight is enabled if the current value is non-zero

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Indan Zupancic <[email protected]>

commit c8303e7f3f3093c16ef0fa5f73280637c89d4368 upstream.

... and not if the maximum is non-zero. This fixes the typo introduced in 47356eb6728501452 and preserves the backlight value from boot.

[ickle: My thanks also to Indan Zupancic for diagnosing the original
regression and suggesting the appropriate fix.]

---
 drivers/gpu/drm/i915/intel_panel.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/i915/intel_panel.c +1 -1
@@ -246,6 +246,6 @@ void intel_panel_setup_backlight(struct
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
-	dev_priv->backlight_level = intel_panel_get_max_backlight(dev);
+	dev_priv->backlight_level = intel_panel_get_backlight(dev);
 	dev_priv->backlight_enabled = dev_priv->backlight_level != 0;
 }
author
#261 lore raw

PATCH 261/272 drm/i915/lvds: Add AOpen i915GMm-HFS to the list of false-positive LVDS

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Knut Petersen <[email protected]>

commit 22ab70d3262ddb6e69b3c246a34e2967ba5eb1e8 upstream.

---
 drivers/gpu/drm/i915/intel_lvds.c |    8 ++++++++
 1 file changed, 8 insertions(+)
drivers/gpu/drm/i915/intel_lvds.c +8 -0
@@ -697,6 +697,14 @@ static const struct dmi_system_id intel_
 	},
 	{
 		.callback = intel_no_lvds_dmi_callback,
+		.ident = "AOpen i915GMm-HFS",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
+			DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
 		.ident = "Aopen i945GTt-VFA",
 		.matches = {
 			DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"),
author
#262 lore raw

PATCH 262/272 drm/i915: Add dependency on CONFIG_TMPFS

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Chris Wilson <[email protected]>

commit f7ab9b407b3bc83161c2aa74c992ba4782e87c9c upstream.

Without tmpfs, shmem_readpage() is not compiled in causing an OOPS as soon as we try to allocate some swappable pages for GEM.

Jan 19 22:52:26 harlie kernel: Modules linked in: i915(+) drm_kms_helper cfbcopyarea video backlight cfbimgblt cfbfillrect
Jan 19 22:52:26 harlie kernel:
Jan 19 22:52:26 harlie kernel: Pid: 1125, comm: modprobe Not tainted 2.6.37Harlie #10 To be filled by O.E.M./To be filled by O.E.M.
Jan 19 22:52:26 harlie kernel: EIP: 0060:[<00000000>] EFLAGS: 00010246 CPU: 3
Jan 19 22:52:26 harlie kernel: EIP is at 0x0
Jan 19 22:52:26 harlie kernel: EAX: 00000000 EBX: f7b7d000 ECX: f3383100 EDX: f7b7d000
Jan 19 22:52:26 harlie kernel: ESI: f1456118 EDI: 00000000 EBP: f2303c98 ESP: f2303c7c
Jan 19 22:52:26 harlie kernel:  DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
Jan 19 22:52:26 harlie kernel: Process modprobe (pid: 1125, ti=f2302000 task=f259cd80 task.ti=f2302000)
Jan 19 22:52:26 harlie kernel: Stack:
Jan 19 22:52:26 harlie udevd-work[1072]: '/sbin/modprobe -b pci:v00008086d00000046sv00000000sd00000000bc03sc00i00' unexpected exit with status 0x0009
Jan 19 22:52:26 harlie kernel:  c1074061 000000d0 f2f42b80 00000000 000a13d2 f2d5dcc0 00000001 f2303cac
Jan 19 22:52:26 harlie kernel:  c107416f 00000000 000a13d2 00000000 f2303cd4 f8d620ed f2cee620 00001000
Jan 19 22:52:26 harlie kernel:  00000000 000a13d2 f1456118 f2d5dcc0 f1a40000 00001000 f2303d04 f8d637ab
Jan 19 22:52:26 harlie kernel: Call Trace:
Jan 19 22:52:26 harlie kernel:  [<c1074061>] ? do_read_cache_page+0x71/0x160
Jan 19 22:52:26 harlie kernel:  [<c107416f>] ? read_cache_page_gfp+0x1f/0x30
Jan 19 22:52:26 harlie kernel:  [<f8d620ed>] ? i915_gem_object_get_pages+0xad/0x1d0 [i915]
Jan 19 22:52:26 harlie kernel:  [<f8d637ab>] ? i915_gem_object_bind_to_gtt+0xeb/0x2d0 [i915]
Jan 19 22:52:26 harlie kernel:  [<f8d65961>] ? i915_gem_object_pin+0x151/0x190 [i915]
Jan 19 22:52:26 harlie kernel:  [<c11e16ed>] ? drm_gem_object_init+0x3d/0x60
Jan 19 22:52:26 harlie kernel:  [<f8d65aa5>] ? i915_gem_init_ringbuffer+0x105/0x1e0 [i915]
Jan 19 22:52:26 harlie kernel:  [<f8d571b7>] ? i915_driver_load+0x667/0x1160 [i915]
---
 drivers/gpu/drm/Kconfig |    3 +++
 1 file changed, 3 insertions(+)
drivers/gpu/drm/Kconfig +3 -0
@@ -100,7 +100,10 @@ config DRM_I830
 config DRM_I915
 	tristate "i915 driver"
 	depends on AGP_INTEL
+	# we need shmfs for the swappable backing store, and in particular
+	# the shmem_readpage() which depends upon tmpfs
 	select SHMEM
+	select TMPFS
 	select DRM_KMS_HELPER
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
author
#263 lore raw

PATCH 263/272 drm/i915: Recognise non-VGA display devices

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Chris Wilson <[email protected]>

commit 934f992c763ae1e5eefcce8af769c16444085df7 upstream.

Starting with SandyBridge (though possible with earlier hacked BIOSes), the BIOS may initialise the IGFX as secondary to a discrete GPU. Prior, it would simply disable the integrated GPU. So we adjust our PCI class mask to match any DISPLAY_CLASS device.

In such a configuration, the IGFX is not a primary VGA controller and so should not take part in VGA arbitration, and the error return from vga_client_register() is expected.

---
 drivers/gpu/drm/i915/i915_dma.c |   10 ++++++++--
 drivers/gpu/drm/i915/i915_drv.c |    2 +-
 drivers/gpu/vga/vgaarb.c        |    2 +-
 3 files changed, 10 insertions(+), 4 deletions(-)
drivers/gpu/drm/i915/i915_dma.c +8 -2
@@ -1243,9 +1243,15 @@ static int i915_load_modeset_init(struct
 	if (ret)
 		DRM_INFO("failed to find VBIOS tables\n");
 
-	/* if we have > 1 VGA cards, then disable the radeon VGA resources */
+	/* If we have > 1 VGA cards, then we need to arbitrate access
+	 * to the common VGA resources.
+	 *
+	 * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA),
+	 * then we do not take part in VGA arbitration and the
+	 * vga_client_register() fails with -ENODEV.
+	 */
 	ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode);
-	if (ret)
+	if (ret && ret != -ENODEV)
 		goto cleanup_ringbuffer;
 
 	intel_register_dsm_handler();
drivers/gpu/drm/i915/i915_drv.c +1 -1
@@ -54,7 +54,7 @@ extern int intel_agp_enabled;
 
 #define INTEL_VGA_DEVICE(id, info) {		\
 	.class = PCI_CLASS_DISPLAY_VGA << 8,	\
-	.class_mask = 0xffff00,			\
+	.class_mask = 0xff0000,			\
 	.vendor = 0x8086,			\
 	.device = id,				\
 	.subvendor = PCI_ANY_ID,		\
drivers/gpu/vga/vgaarb.c +1 -1
@@ -636,7 +636,7 @@ int vga_client_register(struct pci_dev *
 			void (*irq_set_state)(void *cookie, bool state),
 			unsigned int (*set_vga_decode)(void *cookie, bool decode))
 {
-	int ret = -1;
+	int ret = -ENODEV;
 	struct vga_device *vgadev;
 	unsigned long flags;
 
author
#264 lore raw

PATCH 264/272 x86, mm: avoid possible bogus tlb entries by clearing prev mm_cpumask after switching mm

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Suresh Siddha <[email protected]>

commit 831d52bc153971b70e64eccfbed2b232394f22f8 upstream.

Clearing the cpu in prev's mm_cpumask early will avoid the flush tlb IPI's while the cr3 is still pointing to the prev mm. And this window can lead to the possibility of bogus TLB fills resulting in strange failures. One such problematic scenario is mentioned below.

T1. CPU-1 is context switching from mm1 to mm2 context and got a NMI
etc between the point of clearing the cpu from the mm_cpumask(mm1) and before reloading the cr3 with the new mm2.

T2. CPU-2 is tearing down a specific vma for mm1 and will proceed with
flushing the TLB for mm1. It doesn't send the flush TLB to CPU-1 as it doesn't see that cpu listed in the mm_cpumask(mm1).

T3. After the TLB flush is complete, CPU-2 goes ahead and frees the
page-table pages associated with the removed vma mapping.

T4. CPU-2 now allocates those freed page-table pages for something
else.

T5. As the CR3 and TLB caches for mm1 is still active on CPU-1, CPU-1
can potentially speculate and walk through the page-table caches and can insert new TLB entries. As the page-table pages are already freed and being used on CPU-2, this page walk can potentially insert a bogus global TLB entry depending on the (random) contents of the page that is being used on CPU-2.

T6. This bogus TLB entry being global will be active across future CR3
changes and can result in weird memory corruption etc.

To avoid this issue, for the prev mm that is handing over the cpu to another mm, clear the cpu from the mm_cpumask(prev) after the cr3 is changed.

Marking it for -stable, though we haven't seen any reported failure that can be attributed to this.

---
 arch/x86/include/asm/mmu_context.h |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
arch/x86/include/asm/mmu_context.h +3 -2
@@ -36,8 +36,6 @@ static inline void switch_mm(struct mm_s
 	unsigned cpu = smp_processor_id();
 
 	if (likely(prev != next)) {
-		/* stop flush ipis for the previous mm */
-		cpumask_clear_cpu(cpu, mm_cpumask(prev));
 #ifdef CONFIG_SMP
 		percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
 		percpu_write(cpu_tlbstate.active_mm, next);
@@ -47,6 +45,9 @@ static inline void switch_mm(struct mm_s
 		/* Re-load page tables */
 		load_cr3(next->pgd);
 
+		/* stop flush ipis for the previous mm */
+		cpumask_clear_cpu(cpu, mm_cpumask(prev));
+
 		/*
 		 * load the LDT, if the LDT is different:
 		 */
author
#265 lore raw

PATCH 265/272 drm: Only set DPMS ON when actually configuring a mode

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Keith Packard <[email protected]>

commit 811aaa55ba21ab37407018cfc01770d6b037d3fb upstream.

In drm_crtc_helper_set_config, instead of always forcing all outputs to DRM_MODE_DPMS_ON, only set them if the CRTC is actually getting a mode set, as any mode set will turn all outputs on.

This fixes https://lkml.org/lkml/2011/1/24/457

---
 drivers/gpu/drm/drm_crtc_helper.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/gpu/drm/drm_crtc_helper.c +6 -6
@@ -654,6 +654,12 @@ int drm_crtc_helper_set_config(struct dr
 				ret = -EINVAL;
 				goto fail;
 			}
+			DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
+			for (i = 0; i < set->num_connectors; i++) {
+				DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
+					      drm_get_connector_name(set->connectors[i]));
+				set->connectors[i]->dpms = DRM_MODE_DPMS_ON;
+			}
 		}
 		drm_helper_disable_unused_functions(dev);
 	} else if (fb_changed) {
@@ -670,12 +676,6 @@ int drm_crtc_helper_set_config(struct dr
 			goto fail;
 		}
 	}
-	DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
-	for (i = 0; i < set->num_connectors; i++) {
-		DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
-			      drm_get_connector_name(set->connectors[i]));
-		set->connectors[i]->dpms = DRM_MODE_DPMS_ON;
-	}
 
 	kfree(save_connectors);
 	kfree(save_encoders);
author
#266 lore raw

PATCH 266/272 agp: ensure GART has an address before enabling it

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Stephen Kitt <[email protected]>

commit a70b95c017e8b518e1e069853355e4e497453dbb upstream.

Some BIOSs (eg. the AMI BIOS on the Asus P4P800 motherboard) don't initialise the GART address, and pcibios_assign_resources() can ignore it because it can be marked as a host bridge (see
https://bugzilla.kernel.org/show_bug.cgi?id=24392#c5 for details). This was handled correctly up to 2.6.35, but the pci_enable_device() cleanup in 2.6.36 96576a9e1a0cdb8 ("agp: intel-agp: do not use PCI resources before pci_enable_device()") means that the kernel tries to enable the GART before assigning it an address; in such cases the GART overlaps with other device assignments and ends up being disabled.

This patch fixes https://bugzilla.kernel.org/show_bug.cgi?id=24392

Note that I imagine efficeon-agp.c probably has the same problem, but I can't test that and I'd like to make sure this patch is suitable for -stable (since 2.6.36 and 2.6.37 are affected).

Cc Bjorn Helgaas <[email protected]>
Cc Maciej Rutecki <[email protected]>
Cc "Rafael J. Wysocki" <[email protected]>
Cc Kulikov Vasiliy <[email protected]>
Cc Florian Mickler <[email protected]>
---
 drivers/char/agp/intel-agp.c |   27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)
drivers/char/agp/intel-agp.c +16 -11
@@ -774,20 +774,14 @@ static int __devinit agp_intel_probe(str
 	dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name);
 
 	/*
-	* If the device has not been properly setup, the following will catch
-	* the problem and should stop the system from crashing.
-	* 20030610 - [email protected]
-	*/
-	if (pci_enable_device(pdev)) {
-		dev_err(&pdev->dev, "can't enable PCI device\n");
-		agp_put_bridge(bridge);
-		return -ENODEV;
-	}
-
-	/*
 	* The following fixes the case where the BIOS has "forgotten" to
 	* provide an address range for the GART.
 	* 20030610 - [email protected]
+	* This happens before pci_enable_device() intentionally;
+	* calling pci_enable_device() before assigning the resource
+	* will result in the GART being disabled on machines with such
+	* BIOSs (the GART ends up with a BAR starting at 0, which
+	* conflicts a lot of other devices).
 	*/
 	r = &pdev->resource[0];
 	if (!r->start && r->end) {
@@ -798,6 +792,17 @@ static int __devinit agp_intel_probe(str
 		}
 	}
 
+	/*
+	* If the device has not been properly setup, the following will catch
+	* the problem and should stop the system from crashing.
+	* 20030610 - [email protected]
+	*/
+	if (pci_enable_device(pdev)) {
+		dev_err(&pdev->dev, "can't enable PCI device\n");
+		agp_put_bridge(bridge);
+		return -ENODEV;
+	}
+
 	/* Fill in the mode register */
 	if (cap_ptr) {
 		pci_read_config_dword(pdev,
author
#267 lore raw

PATCH 267/272 drm/i915: Only bind to function 0 of the PCI device

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Chris Wilson <[email protected]>

commit 5fe49d86f9d01044abf687a8cd21edef636d58aa upstream.

Early chipsets (gen2/3) used function 1 as a placeholder for multi-head. We used to ignore these since they were not assigned to PCI_CLASS_DISPLAY_VGA. However with 934f992c7 we attempt to bind to all Intel PCI_CLASS_DISPLAY devices (and functions) to work in multi-gpu systems. This fails hard on gen2/3.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=28012

---
 drivers/gpu/drm/i915/i915_drv.c |    8 ++++++++
 1 file changed, 8 insertions(+)
drivers/gpu/drm/i915/i915_drv.c +8 -0
@@ -501,6 +501,14 @@ int i915_reset(struct drm_device *dev, u
 static int __devinit
 i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
+	/* Only bind to function 0 of the device. Early generations
+	 * used function 1 as a placeholder for multi-head. This causes
+	 * us confusion instead, especially on the systems where both
+	 * functions have the same PCI-ID!
+	 */
+	if (PCI_FUNC(pdev->devfn))
+		return -ENODEV;
+
 	return drm_get_pci_dev(pdev, ent, &driver);
 }
 
author
#268 lore raw

PATCH 268/272 xhci: Resume bus on any port status change.

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Sarah Sharp <[email protected]>

commit 7111ebc97ed53a32314011c85a6f235f0dab8ae8 upstream.

The original code that resumed the USB bus on a port status change would only do so when there was a device connected to the port. If a device was just disconnected, the event would be queued for khubd, but khubd wouldn't run. That would leave the connect status change (CSC) bit set.

If a USB device was plugged into that same port, the xHCI host controller would set the current connect status (CCS) bit. But since the CSC bit was already set, it would not generate an interrupt for a port status change event. That would mean the user could "Safely Remove" a device, have the bus suspend, disconnect the device, re-plug it in, and then the device would never be enumerated.

Plugging in a different device on another port would cause the bus to resume, and khubd would notice the re-connected device. Running lsusb would also resume the bus, leading users to report the problem "went away" when using diagnostic tools.

The solution is to resume the bus when a port status change event is received, regardless of the port status.

Thank you very much to Maddog for helping me track down this Heisenbug.

This patch should be queued for the 2.6.37 stable tree.

---
 drivers/usb/host/xhci-ring.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/host/xhci-ring.c +1 -1
@@ -1188,7 +1188,7 @@ static void handle_port_status(struct xh
 
 	addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS * (port_id - 1);
 	temp = xhci_readl(xhci, addr);
-	if ((temp & PORT_CONNECT) && (hcd->state == HC_STATE_SUSPENDED)) {
+	if (hcd->state == HC_STATE_SUSPENDED) {
 		xhci_dbg(xhci, "resume root hub\n");
 		usb_hcd_resume_root_hub(hcd);
 	}
author
#269 lore raw

PATCH 269/272 xHCI: synchronize irq in xhci_suspend()

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Andiry Xu <[email protected]>

commit 0029227f1bc30b6c809ae751f9e7af6cef900997 upstream.

Synchronize the interrupts instead of free them in xhci_suspend(). This will prevent a double free when the host is suspended and then the card removed.

Set the flag hcd->msix_enabled when using MSI-X, and check the flag in suspend_common(). MSI-X synchronization will be handled by xhci_suspend(), and MSI/INTx will be synchronized in suspend_common().

This patch should be queued for the 2.6.37 stable tree.

---
 drivers/usb/core/hcd-pci.c |    7 +++++-
 drivers/usb/host/xhci.c    |   46 ++++++++++++++-------------------------------
 include/linux/usb/hcd.h    |    1 
 3 files changed, 22 insertions(+), 32 deletions(-)
drivers/usb/core/hcd-pci.c +6 -1
@@ -406,7 +406,12 @@ static int suspend_common(struct device
 			return retval;
 	}
 
-	synchronize_irq(pci_dev->irq);
+	/* If MSI-X is enabled, the driver will have synchronized all vectors
+	 * in pci_suspend(). If MSI or legacy PCI is enabled, that will be
+	 * synchronized here.
+	 */
+	if (!hcd->msix_enabled)
+		synchronize_irq(pci_dev->irq);
 
 	/* Downstream ports from this root hub should already be quiesced, so
 	 * there will be no DMA activity.  Now we can shut down the upstream
drivers/usb/host/xhci.c +15 -31

103 lines not on this page · raw message

include/linux/usb/hcd.h +1 -0
@@ -112,6 +112,7 @@ struct usb_hcd {
 	/* Flags that get set only during HCD registration or removal. */
 	unsigned		rh_registered:1;/* is root hub registered? */
 	unsigned		rh_pollable:1;	/* may we poll the root hub? */
+	unsigned		msix_enabled:1;	/* driver has MSI-X enabled? */
 
 	/* The next flag is a stopgap, to be removed when all the HCDs
 	 * support the new root-hub polling mechanism. */
author
#270 lore raw

PATCH 270/272 xhci: Do not run xhci_cleanup_msix with irq disabled

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Zhang Rui <[email protected]>

commit 40a9fb17f32dbe54de3d636142a59288544deed7 upstream.

when unloading xhci_hcd, I got:

[  134.856813] xhci_hcd 0000:02:00.0: remove, state 4
[  134.858140] usb usb3: USB disconnect, address 1
[  134.874956] xhci_hcd 0000:02:00.0: Host controller not halted, aborting reset.
[  134.876351] BUG: sleeping function called from invalid context at kernel/mutex.c:85
[  134.877657] in_atomic(): 0, irqs_disabled(): 1, pid: 1451, name: modprobe
[  134.878975] Pid: 1451, comm: modprobe Not tainted 2.6.37-rc5+ #162
[  134.880298] Call Trace:
[  134.881602]  [<ffffffff8104156a>] __might_sleep+0xeb/0xf0
[  134.882921]  [<ffffffff814763dc>] mutex_lock+0x24/0x50
[  134.884229]  [<ffffffff810a745c>] free_desc+0x2e/0x5f
[  134.885538]  [<ffffffff810a74c8>] irq_free_descs+0x3b/0x71
[  134.886853]  [<ffffffff8102584d>] free_irq_at+0x31/0x36
[  134.888167]  [<ffffffff8102723f>] destroy_irq+0x69/0x71
[  134.889486]  [<ffffffff8102747a>] native_teardown_msi_irq+0xe/0x10
[  134.890820]  [<ffffffff8124c382>] default_teardown_msi_irqs+0x57/0x80
[  134.892158]  [<ffffffff8124be46>] free_msi_irqs+0x8b/0xe9
[  134.893504]  [<ffffffff8124cd46>] pci_disable_msix+0x35/0x39
[  134.894844]  [<ffffffffa01b444a>] xhci_cleanup_msix+0x31/0x51 [xhci_hcd]
[  134.896186]  [<ffffffffa01b4b3a>] xhci_stop+0x3a/0x80 [xhci_hcd]
[  134.897521]  [<ffffffff81341dd4>] usb_remove_hcd+0xfd/0x14a
[  134.898859]  [<ffffffff813500ae>] usb_hcd_pci_remove+0x5c/0xc6
[  134.900193]  [<ffffffff8123c606>] pci_device_remove+0x3f/0x91
[  134.901535]  [<ffffffff812e7ea4>] __device_release_driver+0x83/0xd9
[  134.902899]  [<ffffffff812e8571>] driver_detach+0x86/0xad
[  134.904222]  [<ffffffff812e7d56>] bus_remove_driver+0xb2/0xd8
[  134.905540]  [<ffffffff812e8633>] driver_unregister+0x6c/0x74
[  134.906839]  [<ffffffff8123c8e4>] pci_unregister_driver+0x44/0x89
[  134.908121]  [<ffffffffa01b940e>] xhci_unregister_pci+0x15/0x17 [xhci_hcd]
[  134.909396]  [<ffffffffa01bd7d2>] xhci_hcd_cleanup+0xe/0x10 [xhci_hcd]
[  134.910652]  [<ffffffff8107fcd1>] sys_delete_module+0x1ca/0x23b
[  134.911882]  [<ffffffff81123932>] ? path_put+0x22/0x26
[  134.913104]  [<ffffffff8109a800>] ? audit_syscall_entry+0x2c/0x148
[  134.914333]  [<ffffffff8100ac82>] system_call_fastpath+0x16/0x1b
[  134.915658] xhci_hcd 0000:02:00.0: USB bus 3 deregistered
[  134.916465] xhci_hcd 0000:02:00.0: PCI INT A disabled

and the same issue when xhci_suspend is invoked. (Note from Sarah: That's fixed by Andiry's patch before this, by synchronizing the irqs rather than freeing them on suspend.)

Do not run xhci_cleanup_msix with irq disabled.

This patch should be queued for the 2.6.37 stable tree.

---
 drivers/usb/host/xhci.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/usb/host/xhci.c +4 -2
@@ -512,9 +512,10 @@ void xhci_stop(struct usb_hcd *hcd)
 	spin_lock_irq(&xhci->lock);
 	xhci_halt(xhci);
 	xhci_reset(xhci);
-	xhci_cleanup_msix(xhci);
 	spin_unlock_irq(&xhci->lock);
 
+	xhci_cleanup_msix(xhci);
+
 #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
 	/* Tell the event ring poll function not to reschedule */
 	xhci->zombie = 1;
@@ -548,9 +549,10 @@ void xhci_shutdown(struct usb_hcd *hcd)
 
 	spin_lock_irq(&xhci->lock);
 	xhci_halt(xhci);
-	xhci_cleanup_msix(xhci);
 	spin_unlock_irq(&xhci->lock);
 
+	xhci_cleanup_msix(xhci);
+
 	xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n",
 		    xhci_readl(xhci, &xhci->op_regs->status));
 }
author
#271 lore raw

PATCH 271/272 usb: Realloc xHCI structures after a hub is verified.

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Sarah Sharp <[email protected]>

commit 653a39d1f61bdc9f277766736d21d2e9be0391cb upstream.

When there's an xHCI host power loss after a suspend from memory, the USB core attempts to reset and verify the USB devices that are attached to the system. The xHCI driver has to reallocate those devices, since the hardware lost all knowledge of them during the power loss.

When a hub is plugged in, and the host loses power, the xHCI hardware structures are not updated to say the device is a hub. This is usually done in hub_configure() when the USB hub is detected. That function is skipped during a reset and verify by the USB core, since the core restores the old configuration and alternate settings, and the hub driver has no idea this happened. This bug makes the xHCI host controller reject the enumeration of low speed devices under the resumed hub.

Therefore, make the USB core re-setup the internal xHCI hub device information by calling update_hub_device() when hub_activate() is called for a hub reset resume. After a host power loss, all devices under the roothub get a reset-resume or a disconnect.

This patch should be queued for the 2.6.37 stable tree.

---
 drivers/usb/core/hub.c |   21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
drivers/usb/core/hub.c +21 -0
@@ -677,6 +677,8 @@ static void hub_init_func3(struct work_s
 static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
 {
 	struct usb_device *hdev = hub->hdev;
+	struct usb_hcd *hcd;
+	int ret;
 	int port1;
 	int status;
 	bool need_debounce_delay = false;
@@ -715,6 +717,25 @@ static void hub_activate(struct usb_hub
 			usb_autopm_get_interface_no_resume(
 					to_usb_interface(hub->intfdev));
 			return;		/* Continues at init2: below */
+		} else if (type == HUB_RESET_RESUME) {
+			/* The internal host controller state for the hub device
+			 * may be gone after a host power loss on system resume.
+			 * Update the device's info so the HW knows it's a hub.
+			 */
+			hcd = bus_to_hcd(hdev->bus);
+			if (hcd->driver->update_hub_device) {
+				ret = hcd->driver->update_hub_device(hcd, hdev,
+						&hub->tt, GFP_NOIO);
+				if (ret < 0) {
+					dev_err(hub->intfdev, "Host not "
+							"accepting hub info "
+							"update.\n");
+					dev_err(hub->intfdev, "LS/FS devices "
+							"and hubs may not work "
+							"under this hub\n.");
+				}
+			}
+			hub_power_on(hub, true);
 		} else {
 			hub_power_on(hub, true);
 		}
author
#272 lore raw

PATCH 272/272 xhci: Use GFP_NOIO during device reset.

In reply to Greg KH

2.6.37-stable review patch. If anyone has any objections, please let us know.

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

From: Sarah Sharp <[email protected]>

commit a6d940dd759bf240d28624198660ed34582a327b upstream.

When xhci_discover_or_reset_device() is called after a host controller power loss, the virtual device may need to be reallocated. Make sure xhci_alloc_dev() uses GFP_NOIO. This avoid causing a deadlock by allowing the kernel to flush pending I/O while reallocating memory for a virtual device for a USB mass storage device that's holding the backing store for dirty memory buffers.

This patch should be queued for the 2.6.37 stable tree.

---
 drivers/usb/host/xhci.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/usb/host/xhci.c +6 -2
@@ -2431,8 +2431,12 @@ int xhci_alloc_dev(struct usb_hcd *hcd,
 		xhci_err(xhci, "Error while assigning device slot ID\n");
 		return 0;
 	}
-	/* xhci_alloc_virt_device() does not touch rings; no need to lock */
-	if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_KERNEL)) {
+	/* xhci_alloc_virt_device() does not touch rings; no need to lock.
+	 * Use GFP_NOIO, since this function can be called from
+	 * xhci_discover_or_reset_device(), which may be called as part of
+	 * mass storage driver error handling.
+	 */
+	if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_NOIO)) {
 		/* Disable slot, if we can do it without mem alloc */
 		xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
 		spin_lock_irqsave(&xhci->lock, flags);
#273 lore raw
In reply to Greg KH

I had been submitted the following two backports for 2.6.37.y (only for that) but do not see them in the current batch. I know 270+ is already big and they may come later. Just wanted to ensure they have not fallen through the cracks.

-Stefan

Quoted 1 line

From f1bd6699f775b43bf0ba384dd50a5a8865e1dbd5 Mon Sep 17 00:00:00 2001

From: Stefan Bader <[email protected]>
Date: Thu, 20 Jan 2011 11:37:43 +0100
Subject: [PATCH 1/2] xen: mmu: correctly initialize partial p2m leaf

commit 8e1b4cf2108488ccfb9a3e7ed7cd85a435e01d4b upstream

After changing the p2m mapping to a tree by

commit 58e05027b530ff081ecea68e38de8d59db8f87e0
xen: convert p2m to a 3 level tree

and trying to boot a DomU with 615MB of memory, the following crash was observed in the dump:

kernel direct mapping tables up to 26f00000 @ 1ec4000-1fff000

BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<c0107397>] xen_set_pte+0x27/0x60

*pdpt = 0000000000000000 *pde = 0000000000000000

Adding further debug statements showed that when trying to set up pfn=0x26700 the returned mapping was invalid.

pfn=0x266ff calling set_pte(0xc1fe77f8, 0x6b3003)
pfn=0x26700 calling set_pte(0xc1fe7800, 0x3)

Although the last_pfn obtained from the startup info is 0x26700, which should in turn not be hit, the additional 8MB which are added as extra memory normally seem to be ok. This lead to looking into the initial p2m tree construction, which uses the smaller value and assuming that there is other code handling the extra memory.

When the p2m tree is set up, the leaves are directly pointed to the array which the domain builder set up. But if the mapping is not on a boundary that fits into one p2m page, this will result in the last leaf being only partially valid. And as the invalid entries are not initialized in that case, things go badly wrong.

I am trying to fix that by checking whether the current leaf is a complete map and if not, allocate a completely new page and copy only the valid pointers there. This may not be the most efficient or elegant solution, but at least it seems to allow me booting DomUs with memory assignments all over the range.

[v2: Redid a bit of commit wording and fixed a compile warning]
[backported to 2.6.37]
---
 arch/x86/xen/mmu.c |   20 +++++++++++++++++++-
 1 files changed, 19 insertions(+), 1 deletions(-)
arch/x86/xen/mmu.c +19 -1
index 44924e5..468c9e2 100644
@@ -395,7 +395,25 @@ void __init xen_build_dynamic_phys_to_machine(void)
 			p2m_top[topidx] = mid;
 		}
 
-		p2m_top[topidx][mididx] = &mfn_list[pfn];
+		/*
+		 * As long as the mfn_list has enough entries to completely
+		 * fill a p2m page, pointing into the array is ok. But if
+		 * not the entries beyond the last pfn will be undefined.
+		 * And guessing that the 'what-ever-there-is' does not take it
+		 * too kindly when changing it to invalid markers, a new page
+		 * is allocated, initialized and filled with the valid part.
+		 */
+		if (unlikely(pfn + P2M_PER_PAGE > max_pfn)) {
+			unsigned long p2midx;
+			unsigned long *p2m = extend_brk(PAGE_SIZE, PAGE_SIZE);
+			p2m_init(p2m);
+
+			for (p2midx = 0; pfn + p2midx < max_pfn; p2midx++) {
+				p2m[p2midx] = mfn_list[pfn + p2midx];
+			}
+			p2m_top[topidx][mididx] = p2m;
+		} else
+			p2m_top[topidx][mididx] = &mfn_list[pfn];
 	}
 }
 
Signature · 1 line
1.7.0.4
Quoted 1 line

From c94d1a58392615ce4bf914ba79c1437117d3df57 Mon Sep 17 00:00:00 2001

From: Stefan Bader <[email protected]>
Date: Thu, 27 Jan 2011 10:03:14 -0500
Subject: [PATCH 2/2] xen/p2m: Mark INVALID_P2M_ENTRY the mfn_list past max_pfn.

commit cf04d120d9413de581437cf9a29f138ec1178f65 upstream

In case the mfn_list does not have enough entries to fill a p2m page we do not want the entries from max_pfn up to the boundary to be filled with unknown values. Hence set them to INVALID_P2M_ENTRY.

[backported to 2.6.37]
---
 arch/x86/xen/mmu.c |   18 ++++++------------
 1 files changed, 6 insertions(+), 12 deletions(-)
arch/x86/xen/mmu.c +5 -11
index 468c9e2..198df8d 100644
@@ -399,21 +399,15 @@ void __init xen_build_dynamic_phys_to_machine(void)
 		 * As long as the mfn_list has enough entries to completely
 		 * fill a p2m page, pointing into the array is ok. But if
 		 * not the entries beyond the last pfn will be undefined.
-		 * And guessing that the 'what-ever-there-is' does not take it
-		 * too kindly when changing it to invalid markers, a new page
-		 * is allocated, initialized and filled with the valid part.
 		 */
 		if (unlikely(pfn + P2M_PER_PAGE > max_pfn)) {
 			unsigned long p2midx;
-			unsigned long *p2m = extend_brk(PAGE_SIZE, PAGE_SIZE);
-			p2m_init(p2m);
 
-			for (p2midx = 0; pfn + p2midx < max_pfn; p2midx++) {
-				p2m[p2midx] = mfn_list[pfn + p2midx];
-			}
-			p2m_top[topidx][mididx] = p2m;
-		} else
-			p2m_top[topidx][mididx] = &mfn_list[pfn];
+			p2midx = max_pfn % P2M_PER_PAGE;
+			for ( ; p2midx < P2M_PER_PAGE; p2midx++)
+				mfn_list[pfn + p2midx] = INVALID_P2M_ENTRY;
+		}
+		p2m_top[topidx][mididx] = &mfn_list[pfn];
 	}
 }
 
Signature · 1 line
1.7.0.4
Quoted 1 line

From f1bd6699f775b43bf0ba384dd50a5a8865e1dbd5 Mon Sep 17 00:00:00 2001

From: Stefan Bader <[email protected]>
Date: Thu, 20 Jan 2011 11:37:43 +0100
Subject: [PATCH 1/2] xen: mmu: correctly initialize partial p2m leaf

commit 8e1b4cf2108488ccfb9a3e7ed7cd85a435e01d4b upstream

After changing the p2m mapping to a tree by

commit 58e05027b530ff081ecea68e38de8d59db8f87e0
xen: convert p2m to a 3 level tree

and trying to boot a DomU with 615MB of memory, the following crash was observed in the dump:

kernel direct mapping tables up to 26f00000 @ 1ec4000-1fff000

BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<c0107397>] xen_set_pte+0x27/0x60

*pdpt = 0000000000000000 *pde = 0000000000000000

Adding further debug statements showed that when trying to set up pfn=0x26700 the returned mapping was invalid.

pfn=0x266ff calling set_pte(0xc1fe77f8, 0x6b3003)
pfn=0x26700 calling set_pte(0xc1fe7800, 0x3)

Although the last_pfn obtained from the startup info is 0x26700, which should in turn not be hit, the additional 8MB which are added as extra memory normally seem to be ok. This lead to looking into the initial p2m tree construction, which uses the smaller value and assuming that there is other code handling the extra memory.

When the p2m tree is set up, the leaves are directly pointed to the array which the domain builder set up. But if the mapping is not on a boundary that fits into one p2m page, this will result in the last leaf being only partially valid. And as the invalid entries are not initialized in that case, things go badly wrong.

I am trying to fix that by checking whether the current leaf is a complete map and if not, allocate a completely new page and copy only the valid pointers there. This may not be the most efficient or elegant solution, but at least it seems to allow me booting DomUs with memory assignments all over the range.

[v2: Redid a bit of commit wording and fixed a compile warning]
[backported to 2.6.37]
---
 arch/x86/xen/mmu.c |   20 +++++++++++++++++++-
 1 files changed, 19 insertions(+), 1 deletions(-)
arch/x86/xen/mmu.c +19 -1
index 44924e5..468c9e2 100644
@@ -395,7 +395,25 @@ void __init xen_build_dynamic_phys_to_machine(void)
 			p2m_top[topidx] = mid;
 		}
 
-		p2m_top[topidx][mididx] = &mfn_list[pfn];
+		/*
+		 * As long as the mfn_list has enough entries to completely
+		 * fill a p2m page, pointing into the array is ok. But if
+		 * not the entries beyond the last pfn will be undefined.
+		 * And guessing that the 'what-ever-there-is' does not take it
+		 * too kindly when changing it to invalid markers, a new page
+		 * is allocated, initialized and filled with the valid part.
+		 */
+		if (unlikely(pfn + P2M_PER_PAGE > max_pfn)) {
+			unsigned long p2midx;
+			unsigned long *p2m = extend_brk(PAGE_SIZE, PAGE_SIZE);
+			p2m_init(p2m);
+
+			for (p2midx = 0; pfn + p2midx < max_pfn; p2midx++) {
+				p2m[p2midx] = mfn_list[pfn + p2midx];
+			}
+			p2m_top[topidx][mididx] = p2m;
+		} else
+			p2m_top[topidx][mididx] = &mfn_list[pfn];
 	}
 }
 
Signature · 1 line
1.7.0.4
Quoted 1 line

From c94d1a58392615ce4bf914ba79c1437117d3df57 Mon Sep 17 00:00:00 2001

From: Stefan Bader <[email protected]>
Date: Thu, 27 Jan 2011 10:03:14 -0500
Subject: [PATCH 2/2] xen/p2m: Mark INVALID_P2M_ENTRY the mfn_list past max_pfn.

commit cf04d120d9413de581437cf9a29f138ec1178f65 upstream

In case the mfn_list does not have enough entries to fill a p2m page we do not want the entries from max_pfn up to the boundary to be filled with unknown values. Hence set them to INVALID_P2M_ENTRY.

[backported to 2.6.37]
---
 arch/x86/xen/mmu.c |   18 ++++++------------
 1 files changed, 6 insertions(+), 12 deletions(-)
arch/x86/xen/mmu.c +5 -11
index 468c9e2..198df8d 100644
@@ -399,21 +399,15 @@ void __init xen_build_dynamic_phys_to_machine(void)
 		 * As long as the mfn_list has enough entries to completely
 		 * fill a p2m page, pointing into the array is ok. But if
 		 * not the entries beyond the last pfn will be undefined.
-		 * And guessing that the 'what-ever-there-is' does not take it
-		 * too kindly when changing it to invalid markers, a new page
-		 * is allocated, initialized and filled with the valid part.
 		 */
 		if (unlikely(pfn + P2M_PER_PAGE > max_pfn)) {
 			unsigned long p2midx;
-			unsigned long *p2m = extend_brk(PAGE_SIZE, PAGE_SIZE);
-			p2m_init(p2m);
 
-			for (p2midx = 0; pfn + p2midx < max_pfn; p2midx++) {
-				p2m[p2midx] = mfn_list[pfn + p2midx];
-			}
-			p2m_top[topidx][mididx] = p2m;
-		} else
-			p2m_top[topidx][mididx] = &mfn_list[pfn];
+			p2midx = max_pfn % P2M_PER_PAGE;
+			for ( ; p2midx < P2M_PER_PAGE; p2midx++)
+				mfn_list[pfn + p2midx] = INVALID_P2M_ENTRY;
+		}
+		p2m_top[topidx][mididx] = &mfn_list[pfn];
 	}
 }
 
Signature · 1 line
1.7.0.4
#274 lore raw
Quoted 3 lines · Stefan Bader

I had been submitted the following two backports for 2.6.37.y (only for that) but do not see them in the current batch. I know 270+ is already big and they may come later. Just wanted to ensure they have not fallen through the cracks.

Hmm, do you want to provide the other variant please?

cf04d120d9413de581437cf9a29f138ec1178f65

#275 lore raw
Quoted 8 lines · Konrad Rzeszutek Wilk
Quoted 3 lines · Stefan Bader

I had been submitted the following two backports for 2.6.37.y (only for that) but do not see them in the current batch. I know 270+ is already big and they may come later. Just wanted to ensure they have not fallen through the cracks.

Hmm, do you want to provide the other variant please?

cf04d120d9413de581437cf9a29f138ec1178f65

That was the second patch. I just submitted both to keep them in line with what went to upstream.

#276 lore raw
Quoted 6 lines · Stefan Bader
Quoted 5 lines · Konrad Rzeszutek Wilk
Quoted 3 lines · Stefan Bader

I had been submitted the following two backports for 2.6.37.y (only for that) but do not see them in the current batch. I know 270+ is already big and they may come later. Just wanted to ensure they have not fallen through the cracks.

Quoted 6 lines
Quoted 3 lines

Hmm, do you want to provide the other variant please?

cf04d120d9413de581437cf9a29f138ec1178f65

That was the second patch. I just submitted both to keep them in line with what went to upstream.

Ohh. Duh! Thanks

author
#277 lore raw
In reply to Stefan Bader
Quoted 3 lines · Stefan Bader

I had been submitted the following two backports for 2.6.37.y (only for that) but do not see them in the current batch. I know 270+ is already big and they may come later. Just wanted to ensure they have not fallen through the cracks.

Did you see my first message in this thread which said that I didn't get through all patches sent to me for this release?

{sigh}

/me wonders why I even write things if no one will read it...

greg k-h

#278 lore raw
In reply to Greg KH
Quoted 3 lines · Greg KH

Note, there are still some patches that people have sent me that did not make it to this release. They will show up in the next one, this one is big enough, as I'm sure you will agree.

Hi Greg,

Commit c42988012ad9 ("drm/nouveau: Only select ACPI_VIDEO if its dependencies are met") is needed to fix a build failure on 2.6.37.

I don't see it in your list, and it seems like the patch wasn't Cc'd to stable, so I just want to make sure you know about it.

Thanks,

Signature · 1 line
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
author
#279 lore raw
Quoted 5 lines · Nick Bowler
Quoted 3 lines · Greg KH

Note, there are still some patches that people have sent me that did not make it to this release. They will show up in the next one, this one is big enough, as I'm sure you will agree.

Quoted 7 lines

Hi Greg,

Commit c42988012ad9 ("drm/nouveau: Only select ACPI_VIDEO if its dependencies are met") is needed to fix a build failure on 2.6.37.

I don't see it in your list, and it seems like the patch wasn't Cc'd to stable, so I just want to make sure you know about it.

It wasn't in my list, and no one let me know about it. I'll let it wait for the .2 release, thanks.

greg k-h