mirror of
https://git.yoctoproject.org/meta-ti
synced 2026-05-07 11:59:49 +00:00
linux-ti33x-psp 3.2: update to 3.2.5
Runtime tested on a beaglebone A3 Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> Signed-off-by: Denys Dmytriyenko <denys@ti.com>
This commit is contained in:
committed by
Denys Dmytriyenko
parent
14f31c3c5a
commit
c4eefd7530
@@ -3,7 +3,7 @@ SOC_FAMILY = "ti33x"
|
||||
require conf/machine/include/tune-cortexa8.inc
|
||||
PREFERRED_PROVIDER_virtual/kernel = "linux-ti33x-psp"
|
||||
# Increase this everytime you change something in the kernel
|
||||
MACHINE_KERNEL_PR = "r2"
|
||||
MACHINE_KERNEL_PR = "r3"
|
||||
|
||||
KERNEL_IMAGETYPE = "uImage"
|
||||
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
From d1fe421bb81064477843db98b4804fec79eae30e Mon Sep 17 00:00:00 2001
|
||||
From: Joe Perches <joe@perches.com>
|
||||
Date: Fri, 9 Dec 2011 13:54:34 -0800
|
||||
Subject: [PATCH 01/49] MAINTAINERS: stable: Update address
|
||||
|
||||
commit bc7a2f3abc636d7cab84258a48e77b08fb5fd3d6 upstream.
|
||||
|
||||
The old address hasn't worked since the great intrusion of August 2011.
|
||||
|
||||
Signed-off-by: Joe Perches <joe@perches.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
MAINTAINERS | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
||||
index 62f1cd3..f986e7d 100644
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -6258,7 +6258,7 @@ F: arch/alpha/kernel/srm_env.c
|
||||
|
||||
STABLE BRANCH
|
||||
M: Greg Kroah-Hartman <greg@kroah.com>
|
||||
-L: stable@kernel.org
|
||||
+L: stable@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
STAGING SUBSYSTEM
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
From 3dc851fe5a59ee0eb306b3a29819ee040ba69a24 Mon Sep 17 00:00:00 2001
|
||||
From: Joe Perches <joe@perches.com>
|
||||
Date: Fri, 9 Dec 2011 14:12:00 -0800
|
||||
Subject: [PATCH 02/49] Documentation: Update stable address
|
||||
|
||||
commit 2eb7f204db51969ea558802a6601d79c2fb273b9 upstream.
|
||||
|
||||
The Japanese/Korean/Chinese versions still need updating.
|
||||
|
||||
Also, the stable kernel 2.6.x.y descriptions are out of date
|
||||
and should be updated as well.
|
||||
|
||||
Signed-off-by: Joe Perches <joe@perches.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
Documentation/HOWTO | 4 ++--
|
||||
Documentation/development-process/5.Posting | 8 ++++----
|
||||
2 files changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/Documentation/HOWTO b/Documentation/HOWTO
|
||||
index 81bc1a9..f7ade3b 100644
|
||||
--- a/Documentation/HOWTO
|
||||
+++ b/Documentation/HOWTO
|
||||
@@ -275,8 +275,8 @@ versions.
|
||||
If no 2.6.x.y kernel is available, then the highest numbered 2.6.x
|
||||
kernel is the current stable kernel.
|
||||
|
||||
-2.6.x.y are maintained by the "stable" team <stable@kernel.org>, and are
|
||||
-released as needs dictate. The normal release period is approximately
|
||||
+2.6.x.y are maintained by the "stable" team <stable@vger.kernel.org>, and
|
||||
+are released as needs dictate. The normal release period is approximately
|
||||
two weeks, but it can be longer if there are no pressing problems. A
|
||||
security-related problem, instead, can cause a release to happen almost
|
||||
instantly.
|
||||
diff --git a/Documentation/development-process/5.Posting b/Documentation/development-process/5.Posting
|
||||
index 903a254..8a48c9b 100644
|
||||
--- a/Documentation/development-process/5.Posting
|
||||
+++ b/Documentation/development-process/5.Posting
|
||||
@@ -271,10 +271,10 @@ copies should go to:
|
||||
the linux-kernel list.
|
||||
|
||||
- If you are fixing a bug, think about whether the fix should go into the
|
||||
- next stable update. If so, stable@kernel.org should get a copy of the
|
||||
- patch. Also add a "Cc: stable@kernel.org" to the tags within the patch
|
||||
- itself; that will cause the stable team to get a notification when your
|
||||
- fix goes into the mainline.
|
||||
+ next stable update. If so, stable@vger.kernel.org should get a copy of
|
||||
+ the patch. Also add a "Cc: stable@vger.kernel.org" to the tags within
|
||||
+ the patch itself; that will cause the stable team to get a notification
|
||||
+ when your fix goes into the mainline.
|
||||
|
||||
When selecting recipients for a patch, it is good to have an idea of who
|
||||
you think will eventually accept the patch and get it merged. While it
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
From 9fa97016831ab21d14565a478dc462f35dfb7d2b Mon Sep 17 00:00:00 2001
|
||||
From: Neil Horman <nhorman@tuxdriver.com>
|
||||
Date: Mon, 2 Jan 2012 15:31:23 -0500
|
||||
Subject: [PATCH 03/49] firmware: Fix an oops on reading fw_priv->fw in sysfs
|
||||
loading file
|
||||
|
||||
commit eea915bb0d1358755f151eaefb8208a2d5f3e10c upstream.
|
||||
|
||||
This oops was reported recently:
|
||||
firmware_loading_store+0xf9/0x17b
|
||||
dev_attr_store+0x20/0x22
|
||||
sysfs_write_file+0x101/0x134
|
||||
vfs_write+0xac/0xf3
|
||||
sys_write+0x4a/0x6e
|
||||
system_call_fastpath+0x16/0x1b
|
||||
|
||||
The complete backtrace was unfortunately not captured, but details can be found
|
||||
here:
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=769920
|
||||
|
||||
The cause is fairly clear.
|
||||
|
||||
Its caused by the fact that firmware_loading_store has a case 0 in its
|
||||
switch statement that reads and writes the fw_priv->fw poniter without the
|
||||
protection of the fw_lock mutex. since there is a window between the time that
|
||||
_request_firmware sets fw_priv->fw to NULL and the time the corresponding sysfs
|
||||
file is unregistered, its possible for a user space application to race in, and
|
||||
write a zero to the loading file, causing a NULL dereference in
|
||||
firmware_loading_store. Fix it by extending the protection of the fw_lock mutex
|
||||
to cover all of the firware_loading_store function.
|
||||
|
||||
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/base/firmware_class.c | 14 +++++++-------
|
||||
1 files changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
|
||||
index 06ed6b4..3719c94 100644
|
||||
--- a/drivers/base/firmware_class.c
|
||||
+++ b/drivers/base/firmware_class.c
|
||||
@@ -226,13 +226,13 @@ static ssize_t firmware_loading_store(struct device *dev,
|
||||
int loading = simple_strtol(buf, NULL, 10);
|
||||
int i;
|
||||
|
||||
+ mutex_lock(&fw_lock);
|
||||
+
|
||||
+ if (!fw_priv->fw)
|
||||
+ goto out;
|
||||
+
|
||||
switch (loading) {
|
||||
case 1:
|
||||
- mutex_lock(&fw_lock);
|
||||
- if (!fw_priv->fw) {
|
||||
- mutex_unlock(&fw_lock);
|
||||
- break;
|
||||
- }
|
||||
firmware_free_data(fw_priv->fw);
|
||||
memset(fw_priv->fw, 0, sizeof(struct firmware));
|
||||
/* If the pages are not owned by 'struct firmware' */
|
||||
@@ -243,7 +243,6 @@ static ssize_t firmware_loading_store(struct device *dev,
|
||||
fw_priv->page_array_size = 0;
|
||||
fw_priv->nr_pages = 0;
|
||||
set_bit(FW_STATUS_LOADING, &fw_priv->status);
|
||||
- mutex_unlock(&fw_lock);
|
||||
break;
|
||||
case 0:
|
||||
if (test_bit(FW_STATUS_LOADING, &fw_priv->status)) {
|
||||
@@ -274,7 +273,8 @@ static ssize_t firmware_loading_store(struct device *dev,
|
||||
fw_load_abort(fw_priv);
|
||||
break;
|
||||
}
|
||||
-
|
||||
+out:
|
||||
+ mutex_unlock(&fw_lock);
|
||||
return count;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
From c64f87400ad7f27c043d969e695b3b2384e8a246 Mon Sep 17 00:00:00 2001
|
||||
From: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Date: Tue, 27 Dec 2011 12:22:51 -0600
|
||||
Subject: [PATCH 04/49] rt2800usb: Move ID out of unknown
|
||||
|
||||
commit 3f81f8f1524ccca24df1029b0cf825ecef5e5cdc upstream.
|
||||
|
||||
Testing on the openSUSE wireless forum has shown that a Linksys
|
||||
WUSB54GC v3 with USB ID 1737:0077 works with rt2800usb when the ID is
|
||||
written to /sys/.../new_id. This ID can therefore be moved out of UNKNOWN.
|
||||
|
||||
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Acked-by: Gertjan van Wingerde <gwingerde@gmail.com>
|
||||
Acked-by: Ivo van Doorn <IvDoorn@gmail.com>
|
||||
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/net/wireless/rt2x00/rt2800usb.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
|
||||
index 3778763..3265b34 100644
|
||||
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
|
||||
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
|
||||
@@ -976,6 +976,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
|
||||
{ USB_DEVICE(0x13b1, 0x0031) },
|
||||
{ USB_DEVICE(0x1737, 0x0070) },
|
||||
{ USB_DEVICE(0x1737, 0x0071) },
|
||||
+ { USB_DEVICE(0x1737, 0x0077) },
|
||||
/* Logitec */
|
||||
{ USB_DEVICE(0x0789, 0x0162) },
|
||||
{ USB_DEVICE(0x0789, 0x0163) },
|
||||
@@ -1171,7 +1172,6 @@ static struct usb_device_id rt2800usb_device_table[] = {
|
||||
{ USB_DEVICE(0x1740, 0x0605) },
|
||||
{ USB_DEVICE(0x1740, 0x0615) },
|
||||
/* Linksys */
|
||||
- { USB_DEVICE(0x1737, 0x0077) },
|
||||
{ USB_DEVICE(0x1737, 0x0078) },
|
||||
/* Logitec */
|
||||
{ USB_DEVICE(0x0789, 0x0168) },
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
From 698d2012f8540d1cedc1f49013ba320e382cd1d9 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Date: Wed, 28 Dec 2011 00:10:16 +0000
|
||||
Subject: [PATCH 05/49] offb: Fix setting of the pseudo-palette for >8bpp
|
||||
|
||||
commit 1bb0b7d21584b3f878e2bc880db62351ddee5185 upstream.
|
||||
|
||||
When using a >8bpp framebuffer, offb advertises truecolor, not directcolor,
|
||||
and doesn't touch the color map even if it has a corresponding access method
|
||||
for the real hardware.
|
||||
|
||||
Thus it needs to set the pseudo-palette with all 3 components of the color,
|
||||
like other truecolor framebuffers, not with copies of the color index like
|
||||
a directcolor framebuffer would do.
|
||||
|
||||
This went unnoticed for a long time because it's pretty hard to get offb
|
||||
to kick in with anything but 8bpp (old BootX under MacOS will do that and
|
||||
qemu does it).
|
||||
|
||||
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/video/offb.c | 50 +++++++++++++++++++++++---------------------------
|
||||
1 files changed, 23 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
|
||||
index cb163a5..24e1fc6 100644
|
||||
--- a/drivers/video/offb.c
|
||||
+++ b/drivers/video/offb.c
|
||||
@@ -100,36 +100,32 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
|
||||
u_int transp, struct fb_info *info)
|
||||
{
|
||||
struct offb_par *par = (struct offb_par *) info->par;
|
||||
- int i, depth;
|
||||
- u32 *pal = info->pseudo_palette;
|
||||
-
|
||||
- depth = info->var.bits_per_pixel;
|
||||
- if (depth == 16)
|
||||
- depth = (info->var.green.length == 5) ? 15 : 16;
|
||||
-
|
||||
- if (regno > 255 ||
|
||||
- (depth == 16 && regno > 63) ||
|
||||
- (depth == 15 && regno > 31))
|
||||
- return 1;
|
||||
-
|
||||
- if (regno < 16) {
|
||||
- switch (depth) {
|
||||
- case 15:
|
||||
- pal[regno] = (regno << 10) | (regno << 5) | regno;
|
||||
- break;
|
||||
- case 16:
|
||||
- pal[regno] = (regno << 11) | (regno << 5) | regno;
|
||||
- break;
|
||||
- case 24:
|
||||
- pal[regno] = (regno << 16) | (regno << 8) | regno;
|
||||
- break;
|
||||
- case 32:
|
||||
- i = (regno << 8) | regno;
|
||||
- pal[regno] = (i << 16) | i;
|
||||
- break;
|
||||
+
|
||||
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
|
||||
+ u32 *pal = info->pseudo_palette;
|
||||
+ u32 cr = red >> (16 - info->var.red.length);
|
||||
+ u32 cg = green >> (16 - info->var.green.length);
|
||||
+ u32 cb = blue >> (16 - info->var.blue.length);
|
||||
+ u32 value;
|
||||
+
|
||||
+ if (regno >= 16)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ value = (cr << info->var.red.offset) |
|
||||
+ (cg << info->var.green.offset) |
|
||||
+ (cb << info->var.blue.offset);
|
||||
+ if (info->var.transp.length > 0) {
|
||||
+ u32 mask = (1 << info->var.transp.length) - 1;
|
||||
+ mask <<= info->var.transp.offset;
|
||||
+ value |= mask;
|
||||
}
|
||||
+ pal[regno] = value;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
+ if (regno > 255)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
red >>= 8;
|
||||
green >>= 8;
|
||||
blue >>= 8;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
From 37c7c45ec59ce80eaedb2b8edc4b797e4ad0ef03 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Date: Tue, 3 Jan 2012 12:09:15 +1100
|
||||
Subject: [PATCH 06/49] offb: Fix bug in calculating requested vram size
|
||||
|
||||
commit c055fe0797b7bd8f6f21a13598a55a16d5c13ae7 upstream.
|
||||
|
||||
We used to try to request 8 times more vram than needed, which would
|
||||
fail if the card has a too small BAR (observed with qemu & kvm).
|
||||
|
||||
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/video/offb.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
|
||||
index 24e1fc6..3251a02 100644
|
||||
--- a/drivers/video/offb.c
|
||||
+++ b/drivers/video/offb.c
|
||||
@@ -377,7 +377,7 @@ static void __init offb_init_fb(const char *name, const char *full_name,
|
||||
int pitch, unsigned long address,
|
||||
int foreign_endian, struct device_node *dp)
|
||||
{
|
||||
- unsigned long res_size = pitch * height * (depth + 7) / 8;
|
||||
+ unsigned long res_size = pitch * height;
|
||||
struct offb_par *par = &default_par;
|
||||
unsigned long res_start = address;
|
||||
struct fb_fix_screeninfo *fix;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
From 3184baa0e69e6ad327808b91e0d915090c59b99b Mon Sep 17 00:00:00 2001
|
||||
From: Andres Salomon <dilinger@queued.net>
|
||||
Date: Mon, 19 Dec 2011 12:22:58 -0800
|
||||
Subject: [PATCH 07/49] libertas: clean up scan thread handling
|
||||
|
||||
commit afbca95f95f2bf7283a72670c24c1f6de00b1cb5 upstream.
|
||||
|
||||
The libertas scan thread expects priv->scan_req to be non-NULL. In theory,
|
||||
it should always be set. In practice, we've seen the following oops:
|
||||
|
||||
[ 8363.067444] Unable to handle kernel NULL pointer dereference at virtual address 00000004
|
||||
[ 8363.067490] pgd = c0004000
|
||||
[ 8363.078393] [00000004] *pgd=00000000
|
||||
[ 8363.086711] Internal error: Oops: 17 [#1] PREEMPT
|
||||
[ 8363.091375] Modules linked in: fuse libertas_sdio libertas psmouse mousedev ov7670 mmp_camera joydev videobuf2_core videobuf2_dma_sg videobuf2_memops [last unloaded: scsi_wait_scan]
|
||||
[ 8363.107490] CPU: 0 Not tainted (3.0.0-gf7ccc69 #671)
|
||||
[ 8363.112799] PC is at lbs_scan_worker+0x108/0x5a4 [libertas]
|
||||
[ 8363.118326] LR is at 0x0
|
||||
[ 8363.120836] pc : [<bf03a854>] lr : [<00000000>] psr: 60000113
|
||||
[ 8363.120845] sp : ee66bf48 ip : 00000000 fp : 00000000
|
||||
[ 8363.120845] r10: ee2c2088 r9 : c04e2efc r8 : eef97005
|
||||
[ 8363.132231] r7 : eee0716f r6 : ee2c02c0 r5 : ee2c2088 r4 : eee07160
|
||||
[ 8363.137419] r3 : 00000000 r2 : a0000113 r1 : 00000001 r0 : eee07160
|
||||
[ 8363.143896] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel
|
||||
[ 8363.157630] Control: 10c5387d Table: 2e754019 DAC: 00000015
|
||||
[ 8363.163334] Process kworker/u:1 (pid: 25, stack limit = 0xee66a2f8)
|
||||
|
||||
While I've not found a smoking gun, there are two places that raised red flags
|
||||
for me. The first is in _internal_start_scan, when we queue up a scan; we
|
||||
first queue the worker, and then set priv->scan_req. There's theoretically
|
||||
a 50mS delay which should be plenty, but doing things that way just seems
|
||||
racy (and not in the good way).
|
||||
|
||||
The second is in the scan worker thread itself. Depending on the state of
|
||||
priv->scan_channel, we cancel pending scan runs and then requeue a run in
|
||||
300mS. We then send the scan command down to the hardware, sleep, and if
|
||||
we get scan results for all the desired channels, we set priv->scan_req to
|
||||
NULL. However, it that's happened in less than 300mS, what happens with
|
||||
the pending scan run?
|
||||
|
||||
This patch addresses both of those concerns. With the patch applied, we
|
||||
have not seen the oops in the past two weeks.
|
||||
|
||||
Signed-off-by: Andres Salomon <dilinger@queued.net>
|
||||
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/net/wireless/libertas/cfg.c | 10 ++++++----
|
||||
1 files changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
|
||||
index a7f1ab2..db64ef1 100644
|
||||
--- a/drivers/net/wireless/libertas/cfg.c
|
||||
+++ b/drivers/net/wireless/libertas/cfg.c
|
||||
@@ -728,9 +728,11 @@ static void lbs_scan_worker(struct work_struct *work)
|
||||
le16_to_cpu(scan_cmd->hdr.size),
|
||||
lbs_ret_scan, 0);
|
||||
|
||||
- if (priv->scan_channel >= priv->scan_req->n_channels)
|
||||
+ if (priv->scan_channel >= priv->scan_req->n_channels) {
|
||||
/* Mark scan done */
|
||||
+ cancel_delayed_work(&priv->scan_work);
|
||||
lbs_scan_done(priv);
|
||||
+ }
|
||||
|
||||
/* Restart network */
|
||||
if (carrier)
|
||||
@@ -759,12 +761,12 @@ static void _internal_start_scan(struct lbs_private *priv, bool internal,
|
||||
request->n_ssids, request->n_channels, request->ie_len);
|
||||
|
||||
priv->scan_channel = 0;
|
||||
- queue_delayed_work(priv->work_thread, &priv->scan_work,
|
||||
- msecs_to_jiffies(50));
|
||||
-
|
||||
priv->scan_req = request;
|
||||
priv->internal_scan = internal;
|
||||
|
||||
+ queue_delayed_work(priv->work_thread, &priv->scan_work,
|
||||
+ msecs_to_jiffies(50));
|
||||
+
|
||||
lbs_deb_leave(LBS_DEB_CFG80211);
|
||||
}
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
From 84c0b10f18c54e0f669f9ac81872db6aff1e59b4 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Fri, 9 Dec 2011 22:16:07 +0100
|
||||
Subject: [PATCH 08/49] bcma: support for suspend and resume
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
commit 775ab52142b02237a54184238e922251c59a2b5c upstream.
|
||||
|
||||
bcma used to lock up machine without enabling PCI or initializing CC.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
|
||||
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/bcma/bcma_private.h | 3 +++
|
||||
drivers/bcma/host_pci.c | 37 +++++++++++++++++++++++++++++++++++++
|
||||
drivers/bcma/main.c | 16 ++++++++++++++++
|
||||
3 files changed, 56 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
|
||||
index 30a3085..fda56bd 100644
|
||||
--- a/drivers/bcma/bcma_private.h
|
||||
+++ b/drivers/bcma/bcma_private.h
|
||||
@@ -18,6 +18,9 @@ void bcma_bus_unregister(struct bcma_bus *bus);
|
||||
int __init bcma_bus_early_register(struct bcma_bus *bus,
|
||||
struct bcma_device *core_cc,
|
||||
struct bcma_device *core_mips);
|
||||
+#ifdef CONFIG_PM
|
||||
+int bcma_bus_resume(struct bcma_bus *bus);
|
||||
+#endif
|
||||
|
||||
/* scan.c */
|
||||
int bcma_bus_scan(struct bcma_bus *bus);
|
||||
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
|
||||
index 1b51d8b..990f5a8 100644
|
||||
--- a/drivers/bcma/host_pci.c
|
||||
+++ b/drivers/bcma/host_pci.c
|
||||
@@ -224,6 +224,41 @@ static void bcma_host_pci_remove(struct pci_dev *dev)
|
||||
pci_set_drvdata(dev, NULL);
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_PM
|
||||
+static int bcma_host_pci_suspend(struct pci_dev *dev, pm_message_t state)
|
||||
+{
|
||||
+ /* Host specific */
|
||||
+ pci_save_state(dev);
|
||||
+ pci_disable_device(dev);
|
||||
+ pci_set_power_state(dev, pci_choose_state(dev, state));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int bcma_host_pci_resume(struct pci_dev *dev)
|
||||
+{
|
||||
+ struct bcma_bus *bus = pci_get_drvdata(dev);
|
||||
+ int err;
|
||||
+
|
||||
+ /* Host specific */
|
||||
+ pci_set_power_state(dev, 0);
|
||||
+ err = pci_enable_device(dev);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ pci_restore_state(dev);
|
||||
+
|
||||
+ /* Bus specific */
|
||||
+ err = bcma_bus_resume(bus);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#else /* CONFIG_PM */
|
||||
+# define bcma_host_pci_suspend NULL
|
||||
+# define bcma_host_pci_resume NULL
|
||||
+#endif /* CONFIG_PM */
|
||||
+
|
||||
static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
|
||||
@@ -239,6 +274,8 @@ static struct pci_driver bcma_pci_bridge_driver = {
|
||||
.id_table = bcma_pci_bridge_tbl,
|
||||
.probe = bcma_host_pci_probe,
|
||||
.remove = bcma_host_pci_remove,
|
||||
+ .suspend = bcma_host_pci_suspend,
|
||||
+ .resume = bcma_host_pci_resume,
|
||||
};
|
||||
|
||||
int __init bcma_host_pci_init(void)
|
||||
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
|
||||
index 70c84b9..10f92b3 100644
|
||||
--- a/drivers/bcma/main.c
|
||||
+++ b/drivers/bcma/main.c
|
||||
@@ -240,6 +240,22 @@ int __init bcma_bus_early_register(struct bcma_bus *bus,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_PM
|
||||
+int bcma_bus_resume(struct bcma_bus *bus)
|
||||
+{
|
||||
+ struct bcma_device *core;
|
||||
+
|
||||
+ /* Init CC core */
|
||||
+ core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
|
||||
+ if (core) {
|
||||
+ bus->drv_cc.setup_done = false;
|
||||
+ bcma_core_chipcommon_init(&bus->drv_cc);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
|
||||
{
|
||||
drv->drv.name = drv->name;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
From aa9c7fd565d04120156ef720235e9a759638606a Mon Sep 17 00:00:00 2001
|
||||
From: Pontus Fuchs <pontus.fuchs@gmail.com>
|
||||
Date: Tue, 18 Oct 2011 09:23:41 +0200
|
||||
Subject: [PATCH 09/49] wl12xx: Validate FEM index from ini file and FW
|
||||
|
||||
commit 2131d3c2f99b081806fdae7662c92fe6acda52af upstream.
|
||||
|
||||
Check for out of bound FEM index to prevent reading beyond ini
|
||||
memory end.
|
||||
|
||||
Signed-off-by: Pontus Fuchs <pontus.fuchs@gmail.com>
|
||||
Reviewed-by: Luciano Coelho <coelho@ti.com>
|
||||
Signed-off-by: Luciano Coelho <coelho@ti.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/net/wireless/wl12xx/cmd.c | 22 ++++++++++++++++++++++
|
||||
1 files changed, 22 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
|
||||
index a52299e..54a0d66 100644
|
||||
--- a/drivers/net/wireless/wl12xx/cmd.c
|
||||
+++ b/drivers/net/wireless/wl12xx/cmd.c
|
||||
@@ -120,6 +120,11 @@ int wl1271_cmd_general_parms(struct wl1271 *wl)
|
||||
if (!wl->nvs)
|
||||
return -ENODEV;
|
||||
|
||||
+ if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
|
||||
+ wl1271_warning("FEM index from INI out of bounds");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
|
||||
if (!gen_parms)
|
||||
return -ENOMEM;
|
||||
@@ -143,6 +148,12 @@ int wl1271_cmd_general_parms(struct wl1271 *wl)
|
||||
gp->tx_bip_fem_manufacturer =
|
||||
gen_parms->general_params.tx_bip_fem_manufacturer;
|
||||
|
||||
+ if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
|
||||
+ wl1271_warning("FEM index from FW out of bounds");
|
||||
+ ret = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
|
||||
answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
|
||||
|
||||
@@ -162,6 +173,11 @@ int wl128x_cmd_general_parms(struct wl1271 *wl)
|
||||
if (!wl->nvs)
|
||||
return -ENODEV;
|
||||
|
||||
+ if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
|
||||
+ wl1271_warning("FEM index from ini out of bounds");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
|
||||
if (!gen_parms)
|
||||
return -ENOMEM;
|
||||
@@ -186,6 +202,12 @@ int wl128x_cmd_general_parms(struct wl1271 *wl)
|
||||
gp->tx_bip_fem_manufacturer =
|
||||
gen_parms->general_params.tx_bip_fem_manufacturer;
|
||||
|
||||
+ if (gp->tx_bip_fem_manufacturer >= WL1271_INI_FEM_MODULE_COUNT) {
|
||||
+ wl1271_warning("FEM index from FW out of bounds");
|
||||
+ ret = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
|
||||
answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
From bcd7880977c293b60ae6dbae4264d6c47be08fb9 Mon Sep 17 00:00:00 2001
|
||||
From: Pontus Fuchs <pontus.fuchs@gmail.com>
|
||||
Date: Tue, 18 Oct 2011 09:23:42 +0200
|
||||
Subject: [PATCH 10/49] wl12xx: Check buffer bound when processing nvs data
|
||||
|
||||
commit f6efe96edd9c41c624c8f4ddbc4930c1a2d8f1e1 upstream.
|
||||
|
||||
An nvs with malformed contents could cause the processing of the
|
||||
calibration data to read beyond the end of the buffer. Prevent this
|
||||
from happening by adding bound checking.
|
||||
|
||||
Signed-off-by: Pontus Fuchs <pontus.fuchs@gmail.com>
|
||||
Reviewed-by: Luciano Coelho <coelho@ti.com>
|
||||
Signed-off-by: Luciano Coelho <coelho@ti.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/net/wireless/wl12xx/boot.c | 14 ++++++++++++++
|
||||
1 files changed, 14 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
|
||||
index 6813379..a7b327d 100644
|
||||
--- a/drivers/net/wireless/wl12xx/boot.c
|
||||
+++ b/drivers/net/wireless/wl12xx/boot.c
|
||||
@@ -347,6 +347,9 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
|
||||
nvs_ptr += 3;
|
||||
|
||||
for (i = 0; i < burst_len; i++) {
|
||||
+ if (nvs_ptr + 3 >= (u8 *) wl->nvs + nvs_len)
|
||||
+ goto out_badnvs;
|
||||
+
|
||||
val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
|
||||
| (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
|
||||
|
||||
@@ -358,6 +361,9 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
|
||||
nvs_ptr += 4;
|
||||
dest_addr += 4;
|
||||
}
|
||||
+
|
||||
+ if (nvs_ptr >= (u8 *) wl->nvs + nvs_len)
|
||||
+ goto out_badnvs;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -369,6 +375,10 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
|
||||
*/
|
||||
nvs_ptr = (u8 *)wl->nvs +
|
||||
ALIGN(nvs_ptr - (u8 *)wl->nvs + 7, 4);
|
||||
+
|
||||
+ if (nvs_ptr >= (u8 *) wl->nvs + nvs_len)
|
||||
+ goto out_badnvs;
|
||||
+
|
||||
nvs_len -= nvs_ptr - (u8 *)wl->nvs;
|
||||
|
||||
/* Now we must set the partition correctly */
|
||||
@@ -384,6 +394,10 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
|
||||
|
||||
kfree(nvs_aligned);
|
||||
return 0;
|
||||
+
|
||||
+out_badnvs:
|
||||
+ wl1271_error("nvs data is malformed");
|
||||
+ return -EILSEQ;
|
||||
}
|
||||
|
||||
static void wl1271_boot_enable_interrupts(struct wl1271 *wl)
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
From 78848b4805314cdbf6c342b8315cdf7db2a1d09e Mon Sep 17 00:00:00 2001
|
||||
From: Pontus Fuchs <pontus.fuchs@gmail.com>
|
||||
Date: Thu, 1 Dec 2011 12:13:44 +0100
|
||||
Subject: [PATCH 11/49] wl12xx: Restore testmode ABI
|
||||
|
||||
commit 3f1764945eaac532c20ab1f23afa352a40f797b2 upstream.
|
||||
|
||||
Commit 80900d0140a7648587982c8f299830e900e49165 accidently broke
|
||||
the ABI for testmode commands. Restore the ABI again.
|
||||
|
||||
Signed-off-by: Pontus Fuchs <pontus.fuchs@gmail.com>
|
||||
Signed-off-by: Luciano Coelho <coelho@ti.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/net/wireless/wl12xx/testmode.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/wl12xx/testmode.c
|
||||
index 4ae8eff..abfb120 100644
|
||||
--- a/drivers/net/wireless/wl12xx/testmode.c
|
||||
+++ b/drivers/net/wireless/wl12xx/testmode.c
|
||||
@@ -36,6 +36,7 @@ enum wl1271_tm_commands {
|
||||
WL1271_TM_CMD_TEST,
|
||||
WL1271_TM_CMD_INTERROGATE,
|
||||
WL1271_TM_CMD_CONFIGURE,
|
||||
+ WL1271_TM_CMD_NVS_PUSH, /* Not in use. Keep to not break ABI */
|
||||
WL1271_TM_CMD_SET_PLT_MODE,
|
||||
WL1271_TM_CMD_RECOVER,
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
From 9c146884a6b099ed8892c056e26eae85019bc2c9 Mon Sep 17 00:00:00 2001
|
||||
From: Anton Blanchard <anton@samba.org>
|
||||
Date: Wed, 23 Nov 2011 20:07:17 +0000
|
||||
Subject: [PATCH 12/49] powerpc/time: Handle wrapping of decrementer
|
||||
|
||||
commit 37fb9a0231ee43d42d069863bdfd567fca2b61af upstream.
|
||||
|
||||
When re-enabling interrupts we have code to handle edge sensitive
|
||||
decrementers by resetting the decrementer to 1 whenever it is negative.
|
||||
If interrupts were disabled long enough that the decrementer wrapped to
|
||||
positive we do nothing. This means interrupts can be delayed for a long
|
||||
time until it finally goes negative again.
|
||||
|
||||
While we hope interrupts are never be disabled long enough for the
|
||||
decrementer to go positive, we have a very good test team that can
|
||||
drive any kernel into the ground. The softlockup data we get back
|
||||
from these fails could be seconds in the future, completely missing
|
||||
the cause of the lockup.
|
||||
|
||||
We already keep track of the timebase of the next event so use that
|
||||
to work out if we should trigger a decrementer exception.
|
||||
|
||||
Signed-off-by: Anton Blanchard <anton@samba.org>
|
||||
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
arch/powerpc/include/asm/time.h | 2 ++
|
||||
arch/powerpc/kernel/irq.c | 15 ++++++---------
|
||||
arch/powerpc/kernel/time.c | 9 +++++++++
|
||||
3 files changed, 17 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h
|
||||
index fe6f7c2..bc3c745 100644
|
||||
--- a/arch/powerpc/include/asm/time.h
|
||||
+++ b/arch/powerpc/include/asm/time.h
|
||||
@@ -219,5 +219,7 @@ DECLARE_PER_CPU(struct cpu_usage, cpu_usage_array);
|
||||
extern void secondary_cpu_time_init(void);
|
||||
extern void iSeries_time_init_early(void);
|
||||
|
||||
+extern void decrementer_check_overflow(void);
|
||||
+
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __POWERPC_TIME_H */
|
||||
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
|
||||
index 5c3c469..745c1e7 100644
|
||||
--- a/arch/powerpc/kernel/irq.c
|
||||
+++ b/arch/powerpc/kernel/irq.c
|
||||
@@ -164,16 +164,13 @@ notrace void arch_local_irq_restore(unsigned long en)
|
||||
*/
|
||||
local_paca->hard_enabled = en;
|
||||
|
||||
-#ifndef CONFIG_BOOKE
|
||||
- /* On server, re-trigger the decrementer if it went negative since
|
||||
- * some processors only trigger on edge transitions of the sign bit.
|
||||
- *
|
||||
- * BookE has a level sensitive decrementer (latches in TSR) so we
|
||||
- * don't need that
|
||||
+ /*
|
||||
+ * Trigger the decrementer if we have a pending event. Some processors
|
||||
+ * only trigger on edge transitions of the sign bit. We might also
|
||||
+ * have disabled interrupts long enough that the decrementer wrapped
|
||||
+ * to positive.
|
||||
*/
|
||||
- if ((int)mfspr(SPRN_DEC) < 0)
|
||||
- mtspr(SPRN_DEC, 1);
|
||||
-#endif /* CONFIG_BOOKE */
|
||||
+ decrementer_check_overflow();
|
||||
|
||||
/*
|
||||
* Force the delivery of pending soft-disabled interrupts on PS3.
|
||||
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
|
||||
index 522bb1d..5db163c 100644
|
||||
--- a/arch/powerpc/kernel/time.c
|
||||
+++ b/arch/powerpc/kernel/time.c
|
||||
@@ -889,6 +889,15 @@ static void __init clocksource_init(void)
|
||||
clock->name, clock->mult, clock->shift);
|
||||
}
|
||||
|
||||
+void decrementer_check_overflow(void)
|
||||
+{
|
||||
+ u64 now = get_tb_or_rtc();
|
||||
+ struct decrementer_clock *decrementer = &__get_cpu_var(decrementers);
|
||||
+
|
||||
+ if (now >= decrementer->next_tb)
|
||||
+ set_dec(1);
|
||||
+}
|
||||
+
|
||||
static int decrementer_set_next_event(unsigned long evt,
|
||||
struct clock_event_device *dev)
|
||||
{
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
From 78f337d172aafe8577dab8044f26326850b6c5d0 Mon Sep 17 00:00:00 2001
|
||||
From: Li Zhong <zhong@linux.vnet.ibm.com>
|
||||
Date: Sun, 18 Dec 2011 16:03:04 +0000
|
||||
Subject: [PATCH 13/49] powerpc: Fix unpaired probe_hcall_entry and
|
||||
probe_hcall_exit
|
||||
|
||||
commit e4f387d8db3ba3c2dae4d8bdfe7bb5f4fe1bcb0d upstream.
|
||||
|
||||
Unpaired calling of probe_hcall_entry and probe_hcall_exit might happen
|
||||
as following, which could cause incorrect preempt count.
|
||||
|
||||
__trace_hcall_entry => trace_hcall_entry -> probe_hcall_entry =>
|
||||
get_cpu_var => preempt_disable
|
||||
|
||||
__trace_hcall_exit => trace_hcall_exit -> probe_hcall_exit =>
|
||||
put_cpu_var => preempt_enable
|
||||
|
||||
where:
|
||||
A => B and A -> B means A calls B, but
|
||||
=> means A will call B through function name, and B will definitely be
|
||||
called.
|
||||
-> means A will call B through function pointer, so B might not be
|
||||
called if the function pointer is not set.
|
||||
|
||||
So error happens when only one of probe_hcall_entry and probe_hcall_exit
|
||||
get called during a hcall.
|
||||
|
||||
This patch tries to move the preempt count operations from
|
||||
probe_hcall_entry and probe_hcall_exit to its callers.
|
||||
|
||||
Reported-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
|
||||
Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com>
|
||||
Tested-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
|
||||
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
arch/powerpc/platforms/pseries/hvCall_inst.c | 4 +---
|
||||
arch/powerpc/platforms/pseries/lpar.c | 2 ++
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c
|
||||
index f106662..c9311cf 100644
|
||||
--- a/arch/powerpc/platforms/pseries/hvCall_inst.c
|
||||
+++ b/arch/powerpc/platforms/pseries/hvCall_inst.c
|
||||
@@ -109,7 +109,7 @@ static void probe_hcall_entry(void *ignored, unsigned long opcode, unsigned long
|
||||
if (opcode > MAX_HCALL_OPCODE)
|
||||
return;
|
||||
|
||||
- h = &get_cpu_var(hcall_stats)[opcode / 4];
|
||||
+ h = &__get_cpu_var(hcall_stats)[opcode / 4];
|
||||
h->tb_start = mftb();
|
||||
h->purr_start = mfspr(SPRN_PURR);
|
||||
}
|
||||
@@ -126,8 +126,6 @@ static void probe_hcall_exit(void *ignored, unsigned long opcode, unsigned long
|
||||
h->num_calls++;
|
||||
h->tb_total += mftb() - h->tb_start;
|
||||
h->purr_total += mfspr(SPRN_PURR) - h->purr_start;
|
||||
-
|
||||
- put_cpu_var(hcall_stats);
|
||||
}
|
||||
|
||||
static int __init hcall_inst_init(void)
|
||||
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
|
||||
index 27a4950..dc36ea6 100644
|
||||
--- a/arch/powerpc/platforms/pseries/lpar.c
|
||||
+++ b/arch/powerpc/platforms/pseries/lpar.c
|
||||
@@ -554,6 +554,7 @@ void __trace_hcall_entry(unsigned long opcode, unsigned long *args)
|
||||
goto out;
|
||||
|
||||
(*depth)++;
|
||||
+ preempt_disable();
|
||||
trace_hcall_entry(opcode, args);
|
||||
(*depth)--;
|
||||
|
||||
@@ -576,6 +577,7 @@ void __trace_hcall_exit(long opcode, unsigned long retval,
|
||||
|
||||
(*depth)++;
|
||||
trace_hcall_exit(opcode, retval, retbuf);
|
||||
+ preempt_enable();
|
||||
(*depth)--;
|
||||
|
||||
out:
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
From 838487db8eb68ce5fa5417e9ea1333795f172523 Mon Sep 17 00:00:00 2001
|
||||
From: Ram Vepa <ram.vepa@qlogic.com>
|
||||
Date: Fri, 23 Dec 2011 08:01:43 -0500
|
||||
Subject: [PATCH 14/49] IB/qib: Fix a possible data corruption when receiving
|
||||
packets
|
||||
|
||||
commit eddfb675256f49d14e8c5763098afe3eb2c93701 upstream.
|
||||
|
||||
Prevent a receive data corruption by ensuring that the write to update
|
||||
the rcvhdrheadn register to generate an interrupt is at the very end
|
||||
of the receive processing.
|
||||
|
||||
Signed-off-by: Ramkrishna Vepa <ram.vepa@qlogic.com>
|
||||
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@qlogic.com>
|
||||
Signed-off-by: Roland Dreier <roland@purestorage.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/infiniband/hw/qib/qib_iba6120.c | 4 +++-
|
||||
drivers/infiniband/hw/qib/qib_iba7220.c | 4 +++-
|
||||
drivers/infiniband/hw/qib/qib_iba7322.c | 6 ++++--
|
||||
3 files changed, 10 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c
|
||||
index 781a802..4f18e2d 100644
|
||||
--- a/drivers/infiniband/hw/qib/qib_iba6120.c
|
||||
+++ b/drivers/infiniband/hw/qib/qib_iba6120.c
|
||||
@@ -2076,9 +2076,11 @@ static void qib_6120_config_ctxts(struct qib_devdata *dd)
|
||||
static void qib_update_6120_usrhead(struct qib_ctxtdata *rcd, u64 hd,
|
||||
u32 updegr, u32 egrhd, u32 npkts)
|
||||
{
|
||||
- qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
|
||||
if (updegr)
|
||||
qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt);
|
||||
+ mmiowb();
|
||||
+ qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
|
||||
+ mmiowb();
|
||||
}
|
||||
|
||||
static u32 qib_6120_hdrqempty(struct qib_ctxtdata *rcd)
|
||||
diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c
|
||||
index 439d3c5..7ec4048 100644
|
||||
--- a/drivers/infiniband/hw/qib/qib_iba7220.c
|
||||
+++ b/drivers/infiniband/hw/qib/qib_iba7220.c
|
||||
@@ -2725,9 +2725,11 @@ static int qib_7220_set_loopback(struct qib_pportdata *ppd, const char *what)
|
||||
static void qib_update_7220_usrhead(struct qib_ctxtdata *rcd, u64 hd,
|
||||
u32 updegr, u32 egrhd, u32 npkts)
|
||||
{
|
||||
- qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
|
||||
if (updegr)
|
||||
qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt);
|
||||
+ mmiowb();
|
||||
+ qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
|
||||
+ mmiowb();
|
||||
}
|
||||
|
||||
static u32 qib_7220_hdrqempty(struct qib_ctxtdata *rcd)
|
||||
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c
|
||||
index 1d58959..5a070e8 100644
|
||||
--- a/drivers/infiniband/hw/qib/qib_iba7322.c
|
||||
+++ b/drivers/infiniband/hw/qib/qib_iba7322.c
|
||||
@@ -4082,10 +4082,12 @@ static void qib_update_7322_usrhead(struct qib_ctxtdata *rcd, u64 hd,
|
||||
*/
|
||||
if (hd >> IBA7322_HDRHEAD_PKTINT_SHIFT)
|
||||
adjust_rcv_timeout(rcd, npkts);
|
||||
- qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
|
||||
- qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
|
||||
if (updegr)
|
||||
qib_write_ureg(rcd->dd, ur_rcvegrindexhead, egrhd, rcd->ctxt);
|
||||
+ mmiowb();
|
||||
+ qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
|
||||
+ qib_write_ureg(rcd->dd, ur_rcvhdrhead, hd, rcd->ctxt);
|
||||
+ mmiowb();
|
||||
}
|
||||
|
||||
static u32 qib_7322_hdrqempty(struct qib_ctxtdata *rcd)
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
From a2beea13ae4c2ffcaa7f0ddf94fde1246e2e6fc1 Mon Sep 17 00:00:00 2001
|
||||
From: Eli Cohen <eli@dev.mellanox.co.il>
|
||||
Date: Tue, 3 Jan 2012 20:36:48 -0800
|
||||
Subject: [PATCH 15/49] IB/uverbs: Protect QP multicast list
|
||||
|
||||
commit e214a0fe2b382fa302c036ecd6e6ffe99e3b9875 upstream.
|
||||
|
||||
Userspace verbs multicast attach/detach operations on a QP are done
|
||||
while holding the rwsem of the QP for reading. That's not sufficient
|
||||
since a reader lock allows more than one reader to acquire the
|
||||
lock. However, multicast attach/detach does list manipulation that
|
||||
can corrupt the list if multiple threads run in parallel.
|
||||
|
||||
Fix this by acquiring the rwsem as a writer to serialize attach/detach
|
||||
operations. Add idr_write_qp() and put_qp_write() to encapsulate
|
||||
this.
|
||||
|
||||
This fixes oops seen when running applications that perform multicast
|
||||
joins/leaves.
|
||||
|
||||
Reported by: Mike Dubman <miked@mellanox.com>
|
||||
Signed-off-by: Eli Cohen <eli@mellanox.com>
|
||||
Signed-off-by: Roland Dreier <roland@purestorage.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/infiniband/core/uverbs_cmd.c | 21 +++++++++++++++++----
|
||||
1 files changed, 17 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
|
||||
index 254f164..e3db8ef 100644
|
||||
--- a/drivers/infiniband/core/uverbs_cmd.c
|
||||
+++ b/drivers/infiniband/core/uverbs_cmd.c
|
||||
@@ -241,11 +241,24 @@ static struct ib_qp *idr_read_qp(int qp_handle, struct ib_ucontext *context)
|
||||
return idr_read_obj(&ib_uverbs_qp_idr, qp_handle, context, 0);
|
||||
}
|
||||
|
||||
+static struct ib_qp *idr_write_qp(int qp_handle, struct ib_ucontext *context)
|
||||
+{
|
||||
+ struct ib_uobject *uobj;
|
||||
+
|
||||
+ uobj = idr_write_uobj(&ib_uverbs_qp_idr, qp_handle, context);
|
||||
+ return uobj ? uobj->object : NULL;
|
||||
+}
|
||||
+
|
||||
static void put_qp_read(struct ib_qp *qp)
|
||||
{
|
||||
put_uobj_read(qp->uobject);
|
||||
}
|
||||
|
||||
+static void put_qp_write(struct ib_qp *qp)
|
||||
+{
|
||||
+ put_uobj_write(qp->uobject);
|
||||
+}
|
||||
+
|
||||
static struct ib_srq *idr_read_srq(int srq_handle, struct ib_ucontext *context)
|
||||
{
|
||||
return idr_read_obj(&ib_uverbs_srq_idr, srq_handle, context, 0);
|
||||
@@ -2375,7 +2388,7 @@ ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file,
|
||||
if (copy_from_user(&cmd, buf, sizeof cmd))
|
||||
return -EFAULT;
|
||||
|
||||
- qp = idr_read_qp(cmd.qp_handle, file->ucontext);
|
||||
+ qp = idr_write_qp(cmd.qp_handle, file->ucontext);
|
||||
if (!qp)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -2404,7 +2417,7 @@ ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file,
|
||||
kfree(mcast);
|
||||
|
||||
out_put:
|
||||
- put_qp_read(qp);
|
||||
+ put_qp_write(qp);
|
||||
|
||||
return ret ? ret : in_len;
|
||||
}
|
||||
@@ -2422,7 +2435,7 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
|
||||
if (copy_from_user(&cmd, buf, sizeof cmd))
|
||||
return -EFAULT;
|
||||
|
||||
- qp = idr_read_qp(cmd.qp_handle, file->ucontext);
|
||||
+ qp = idr_write_qp(cmd.qp_handle, file->ucontext);
|
||||
if (!qp)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -2441,7 +2454,7 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
|
||||
}
|
||||
|
||||
out_put:
|
||||
- put_qp_read(qp);
|
||||
+ put_qp_write(qp);
|
||||
|
||||
return ret ? ret : in_len;
|
||||
}
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
From 274a64cd739d2b5e33e6e2112f78c896b18849a9 Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Fri, 2 Dec 2011 12:22:54 -0800
|
||||
Subject: [PATCH 16/49] iwlagn: fix TID use bug
|
||||
|
||||
commit 9a215e40d70ae63762963ab3ccc7f31dd966dc6a upstream.
|
||||
|
||||
The driver everywhere uses max TID count as 9,
|
||||
which is wrong, it should be 8.
|
||||
|
||||
I think the reason it uses 9 here is off-by-one
|
||||
confusion by whoever wrote this. We do use the
|
||||
value IWL_MAX_TID_COUNT for "not QoS/no TID"
|
||||
but that is completely correct even if it is 8
|
||||
and not 9 since 0-7 are only valid.
|
||||
|
||||
As a side effect, this fixes the following bug:
|
||||
|
||||
Open BA session requested for 00:23:cd:16:8a:7e tid 8
|
||||
------------[ cut here ]------------
|
||||
kernel BUG at drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h:350!
|
||||
...
|
||||
|
||||
when you do
|
||||
echo "tx start 8" > /sys/kernel/debug/ieee80211/*/*/*/*/agg_status
|
||||
|
||||
Reported-by: Nikolay Martynov <mar.kolya@gmail.com>
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/net/wireless/iwlwifi/iwl-commands.h | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
|
||||
index 69d5f85..8b9ff28 100644
|
||||
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
|
||||
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
|
||||
@@ -809,7 +809,7 @@ struct iwl_qosparam_cmd {
|
||||
#define IWLAGN_STATION_COUNT 16
|
||||
|
||||
#define IWL_INVALID_STATION 255
|
||||
-#define IWL_MAX_TID_COUNT 9
|
||||
+#define IWL_MAX_TID_COUNT 8
|
||||
|
||||
#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2)
|
||||
#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8)
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
From 8de3e18bbd1ec02914f9bf1517d2c3557c666314 Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Mon, 19 Dec 2011 14:00:59 -0800
|
||||
Subject: [PATCH 17/49] iwlagn: fix (remove) use of PAGE_SIZE
|
||||
|
||||
commit 106671369e6d046c0b3e1e72b18ad6dd9cb298b0 upstream.
|
||||
|
||||
The ICT code erroneously uses PAGE_SIZE. The bug
|
||||
is that PAGE_SIZE isn't necessarily 4096, so on
|
||||
such platforms this code will not work correctly
|
||||
as we'll try to attempt to read an index in the
|
||||
table that the device never wrote, it always has
|
||||
4096-byte pages.
|
||||
|
||||
Additionally, the manual alignment code here is
|
||||
unnecessary -- Documentation/DMA-API-HOWTO.txt
|
||||
states:
|
||||
The cpu return address and the DMA bus master address are both
|
||||
guaranteed to be aligned to the smallest PAGE_SIZE order which
|
||||
is greater than or equal to the requested size. This invariant
|
||||
exists (for example) to guarantee that if you allocate a chunk
|
||||
which is smaller than or equal to 64 kilobytes, the extent of the
|
||||
buffer you receive will not cross a 64K boundary.
|
||||
|
||||
Just use appropriate new constants and get rid of
|
||||
the alignment code.
|
||||
|
||||
Cc: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
|
||||
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 2 -
|
||||
drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 73 +++++++++------------
|
||||
2 files changed, 31 insertions(+), 44 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
|
||||
index 2b6756e..5c29281 100644
|
||||
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
|
||||
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
|
||||
@@ -219,9 +219,7 @@ struct iwl_trans_pcie {
|
||||
|
||||
/* INT ICT Table */
|
||||
__le32 *ict_tbl;
|
||||
- void *ict_tbl_vir;
|
||||
dma_addr_t ict_tbl_dma;
|
||||
- dma_addr_t aligned_ict_tbl_dma;
|
||||
int ict_index;
|
||||
u32 inta;
|
||||
bool use_ict;
|
||||
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
|
||||
index 374c68c..1920237 100644
|
||||
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
|
||||
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
|
||||
@@ -1136,7 +1136,11 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
|
||||
* ICT functions
|
||||
*
|
||||
******************************************************************************/
|
||||
-#define ICT_COUNT (PAGE_SIZE/sizeof(u32))
|
||||
+
|
||||
+/* a device (PCI-E) page is 4096 bytes long */
|
||||
+#define ICT_SHIFT 12
|
||||
+#define ICT_SIZE (1 << ICT_SHIFT)
|
||||
+#define ICT_COUNT (ICT_SIZE / sizeof(u32))
|
||||
|
||||
/* Free dram table */
|
||||
void iwl_free_isr_ict(struct iwl_trans *trans)
|
||||
@@ -1144,21 +1148,19 @@ void iwl_free_isr_ict(struct iwl_trans *trans)
|
||||
struct iwl_trans_pcie *trans_pcie =
|
||||
IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
- if (trans_pcie->ict_tbl_vir) {
|
||||
- dma_free_coherent(bus(trans)->dev,
|
||||
- (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
|
||||
- trans_pcie->ict_tbl_vir,
|
||||
+ if (trans_pcie->ict_tbl) {
|
||||
+ dma_free_coherent(bus(trans)->dev, ICT_SIZE,
|
||||
+ trans_pcie->ict_tbl,
|
||||
trans_pcie->ict_tbl_dma);
|
||||
- trans_pcie->ict_tbl_vir = NULL;
|
||||
- memset(&trans_pcie->ict_tbl_dma, 0,
|
||||
- sizeof(trans_pcie->ict_tbl_dma));
|
||||
- memset(&trans_pcie->aligned_ict_tbl_dma, 0,
|
||||
- sizeof(trans_pcie->aligned_ict_tbl_dma));
|
||||
+ trans_pcie->ict_tbl = NULL;
|
||||
+ trans_pcie->ict_tbl_dma = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-/* allocate dram shared table it is a PAGE_SIZE aligned
|
||||
+/*
|
||||
+ * allocate dram shared table, it is an aligned memory
|
||||
+ * block of ICT_SIZE.
|
||||
* also reset all data related to ICT table interrupt.
|
||||
*/
|
||||
int iwl_alloc_isr_ict(struct iwl_trans *trans)
|
||||
@@ -1166,36 +1168,26 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans)
|
||||
struct iwl_trans_pcie *trans_pcie =
|
||||
IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
- /* allocate shrared data table */
|
||||
- trans_pcie->ict_tbl_vir =
|
||||
- dma_alloc_coherent(bus(trans)->dev,
|
||||
- (sizeof(u32) * ICT_COUNT) + PAGE_SIZE,
|
||||
- &trans_pcie->ict_tbl_dma, GFP_KERNEL);
|
||||
- if (!trans_pcie->ict_tbl_vir)
|
||||
+ trans_pcie->ict_tbl =
|
||||
+ dma_alloc_coherent(bus(trans)->dev, ICT_SIZE,
|
||||
+ &trans_pcie->ict_tbl_dma,
|
||||
+ GFP_KERNEL);
|
||||
+ if (!trans_pcie->ict_tbl)
|
||||
return -ENOMEM;
|
||||
|
||||
- /* align table to PAGE_SIZE boundary */
|
||||
- trans_pcie->aligned_ict_tbl_dma =
|
||||
- ALIGN(trans_pcie->ict_tbl_dma, PAGE_SIZE);
|
||||
-
|
||||
- IWL_DEBUG_ISR(trans, "ict dma addr %Lx dma aligned %Lx diff %d\n",
|
||||
- (unsigned long long)trans_pcie->ict_tbl_dma,
|
||||
- (unsigned long long)trans_pcie->aligned_ict_tbl_dma,
|
||||
- (int)(trans_pcie->aligned_ict_tbl_dma -
|
||||
- trans_pcie->ict_tbl_dma));
|
||||
+ /* just an API sanity check ... it is guaranteed to be aligned */
|
||||
+ if (WARN_ON(trans_pcie->ict_tbl_dma & (ICT_SIZE - 1))) {
|
||||
+ iwl_free_isr_ict(trans);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
|
||||
- trans_pcie->ict_tbl = trans_pcie->ict_tbl_vir +
|
||||
- (trans_pcie->aligned_ict_tbl_dma -
|
||||
- trans_pcie->ict_tbl_dma);
|
||||
+ IWL_DEBUG_ISR(trans, "ict dma addr %Lx\n",
|
||||
+ (unsigned long long)trans_pcie->ict_tbl_dma);
|
||||
|
||||
- IWL_DEBUG_ISR(trans, "ict vir addr %p vir aligned %p diff %d\n",
|
||||
- trans_pcie->ict_tbl, trans_pcie->ict_tbl_vir,
|
||||
- (int)(trans_pcie->aligned_ict_tbl_dma -
|
||||
- trans_pcie->ict_tbl_dma));
|
||||
+ IWL_DEBUG_ISR(trans, "ict vir addr %p\n", trans_pcie->ict_tbl);
|
||||
|
||||
/* reset table and index to all 0 */
|
||||
- memset(trans_pcie->ict_tbl_vir, 0,
|
||||
- (sizeof(u32) * ICT_COUNT) + PAGE_SIZE);
|
||||
+ memset(trans_pcie->ict_tbl, 0, ICT_SIZE);
|
||||
trans_pcie->ict_index = 0;
|
||||
|
||||
/* add periodic RX interrupt */
|
||||
@@ -1213,23 +1205,20 @@ int iwl_reset_ict(struct iwl_trans *trans)
|
||||
struct iwl_trans_pcie *trans_pcie =
|
||||
IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
- if (!trans_pcie->ict_tbl_vir)
|
||||
+ if (!trans_pcie->ict_tbl)
|
||||
return 0;
|
||||
|
||||
spin_lock_irqsave(&trans->shrd->lock, flags);
|
||||
iwl_disable_interrupts(trans);
|
||||
|
||||
- memset(&trans_pcie->ict_tbl[0], 0, sizeof(u32) * ICT_COUNT);
|
||||
+ memset(trans_pcie->ict_tbl, 0, ICT_SIZE);
|
||||
|
||||
- val = trans_pcie->aligned_ict_tbl_dma >> PAGE_SHIFT;
|
||||
+ val = trans_pcie->ict_tbl_dma >> ICT_SHIFT;
|
||||
|
||||
val |= CSR_DRAM_INT_TBL_ENABLE;
|
||||
val |= CSR_DRAM_INIT_TBL_WRAP_CHECK;
|
||||
|
||||
- IWL_DEBUG_ISR(trans, "CSR_DRAM_INT_TBL_REG =0x%X "
|
||||
- "aligned dma address %Lx\n",
|
||||
- val,
|
||||
- (unsigned long long)trans_pcie->aligned_ict_tbl_dma);
|
||||
+ IWL_DEBUG_ISR(trans, "CSR_DRAM_INT_TBL_REG =0x%x\n", val);
|
||||
|
||||
iwl_write32(bus(trans), CSR_DRAM_INT_TBL_REG, val);
|
||||
trans_pcie->use_ict = true;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
From 3d69705bbc0503baa930a277c3570ccdc2b82ac1 Mon Sep 17 00:00:00 2001
|
||||
From: Steven Rostedt <srostedt@redhat.com>
|
||||
Date: Fri, 4 Nov 2011 16:32:25 -0400
|
||||
Subject: [PATCH 18/49] perf: Fix parsing of __print_flags() in TP_printk()
|
||||
|
||||
commit 49908a1b25d448d68fd26faca260e1850201575f upstream.
|
||||
|
||||
A update is made to the sched:sched_switch event that adds some
|
||||
logic to the first parameter of the __print_flags() that shows the
|
||||
state of tasks. This change cause perf to fail parsing the flags.
|
||||
|
||||
A simple fix is needed to have the parser be able to process ops
|
||||
within the argument.
|
||||
|
||||
Reported-by: Andrew Vagin <avagin@openvz.org>
|
||||
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
tools/perf/util/trace-event-parse.c | 2 ++
|
||||
1 files changed, 2 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
|
||||
index 6c164dc..bf54c48 100644
|
||||
--- a/tools/perf/util/trace-event-parse.c
|
||||
+++ b/tools/perf/util/trace-event-parse.c
|
||||
@@ -1582,6 +1582,8 @@ process_symbols(struct event *event, struct print_arg *arg, char **tok)
|
||||
field = malloc_or_die(sizeof(*field));
|
||||
|
||||
type = process_arg(event, field, &token);
|
||||
+ while (type == EVENT_OP)
|
||||
+ type = process_op(event, field, &token);
|
||||
if (test_type_token(type, token, EVENT_DELIM, ","))
|
||||
goto out_free;
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
From b892a813649b593177f4b36c200691ec7b610af7 Mon Sep 17 00:00:00 2001
|
||||
From: Boaz Harrosh <bharrosh@panasas.com>
|
||||
Date: Tue, 27 Dec 2011 19:23:36 +0200
|
||||
Subject: [PATCH 19/49] ore: Fix crash in case of an IO error.
|
||||
|
||||
commit ffefb8eaa367e8a5c14f779233d9da1fbc23d164 upstream.
|
||||
|
||||
The users of ore_check_io() expect the reported device
|
||||
(In case of error) to be indexed relative to the passed-in
|
||||
ore_components table, and not the logical dev index.
|
||||
|
||||
This causes a crash inside objlayoutdriver in case of
|
||||
an IO error.
|
||||
|
||||
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
fs/exofs/ore.c | 6 +++---
|
||||
1 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c
|
||||
index d271ad8..894f3e1 100644
|
||||
--- a/fs/exofs/ore.c
|
||||
+++ b/fs/exofs/ore.c
|
||||
@@ -445,10 +445,10 @@ int ore_check_io(struct ore_io_state *ios, ore_on_dev_error on_dev_error)
|
||||
u64 residual = ios->reading ?
|
||||
or->in.residual : or->out.residual;
|
||||
u64 offset = (ios->offset + ios->length) - residual;
|
||||
- struct ore_dev *od = ios->oc->ods[
|
||||
- per_dev->dev - ios->oc->first_dev];
|
||||
+ unsigned dev = per_dev->dev - ios->oc->first_dev;
|
||||
+ struct ore_dev *od = ios->oc->ods[dev];
|
||||
|
||||
- on_dev_error(ios, od, per_dev->dev, osi.osd_err_pri,
|
||||
+ on_dev_error(ios, od, dev, osi.osd_err_pri,
|
||||
offset, residual);
|
||||
}
|
||||
if (osi.osd_err_pri >= acumulated_osd_err) {
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
From 3c8f1a35fab7418f9afeda2618992c1fd5504475 Mon Sep 17 00:00:00 2001
|
||||
From: Boaz Harrosh <bharrosh@panasas.com>
|
||||
Date: Wed, 28 Dec 2011 19:14:23 +0200
|
||||
Subject: [PATCH 20/49] ore: fix BUG_ON, too few sgs when reading
|
||||
|
||||
commit 361aba569f55dd159b850489a3538253afbb3973 upstream.
|
||||
|
||||
When reading RAID5 files, in rare cases, we calculated too
|
||||
few sg segments. There should be two extra for the beginning
|
||||
and end partial units.
|
||||
|
||||
Also "too few sg segments" should not be a BUG_ON there is
|
||||
all the mechanics in place to handle it, as a short read.
|
||||
So just return -ENOMEM and the rest of the code will gracefully
|
||||
split the IO.
|
||||
|
||||
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
fs/exofs/ore.c | 2 +-
|
||||
fs/exofs/ore_raid.c | 6 +++++-
|
||||
2 files changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c
|
||||
index 894f3e1..49cf230 100644
|
||||
--- a/fs/exofs/ore.c
|
||||
+++ b/fs/exofs/ore.c
|
||||
@@ -266,7 +266,7 @@ int ore_get_rw_state(struct ore_layout *layout, struct ore_components *oc,
|
||||
|
||||
/* first/last seg is split */
|
||||
num_raid_units += layout->group_width;
|
||||
- sgs_per_dev = div_u64(num_raid_units, data_devs);
|
||||
+ sgs_per_dev = div_u64(num_raid_units, data_devs) + 2;
|
||||
} else {
|
||||
/* For Writes add parity pages array. */
|
||||
max_par_pages = num_raid_units * pages_in_unit *
|
||||
diff --git a/fs/exofs/ore_raid.c b/fs/exofs/ore_raid.c
|
||||
index 29c47e5..414a2df 100644
|
||||
--- a/fs/exofs/ore_raid.c
|
||||
+++ b/fs/exofs/ore_raid.c
|
||||
@@ -551,7 +551,11 @@ int _ore_add_parity_unit(struct ore_io_state *ios,
|
||||
unsigned cur_len)
|
||||
{
|
||||
if (ios->reading) {
|
||||
- BUG_ON(per_dev->cur_sg >= ios->sgs_per_dev);
|
||||
+ if (per_dev->cur_sg >= ios->sgs_per_dev) {
|
||||
+ ORE_DBGMSG("cur_sg(%d) >= sgs_per_dev(%d)\n" ,
|
||||
+ per_dev->cur_sg, ios->sgs_per_dev);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
_ore_add_sg_seg(per_dev, cur_len, true);
|
||||
} else {
|
||||
struct __stripe_pages_2d *sp2d = ios->sp2d;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
From f3db3efc229dac1097a71b9d793d61aefb033ac2 Mon Sep 17 00:00:00 2001
|
||||
From: Boaz Harrosh <bharrosh@panasas.com>
|
||||
Date: Wed, 28 Dec 2011 19:21:45 +0200
|
||||
Subject: [PATCH 21/49] ore: Must support none-PAGE-aligned IO
|
||||
|
||||
commit 724577ca355795b0a25c93ccbeee927871ca1a77 upstream.
|
||||
|
||||
NFS might send us offsets that are not PAGE aligned. So
|
||||
we must read in the reminder of the first/last pages, in cases
|
||||
we need it for Parity calculations.
|
||||
|
||||
We only add an sg segments to read the partial page. But
|
||||
we don't mark it as read=true because it is a lock-for-write
|
||||
page.
|
||||
|
||||
TODO: In some cases (IO spans a single unit) we can just
|
||||
adjust the raid_unit offset/length, but this is left for
|
||||
later Kernels.
|
||||
|
||||
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
fs/exofs/ore_raid.c | 72 ++++++++++++++++++++++++++++++++++++++++++--------
|
||||
1 files changed, 60 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/fs/exofs/ore_raid.c b/fs/exofs/ore_raid.c
|
||||
index 414a2df..d222c77 100644
|
||||
--- a/fs/exofs/ore_raid.c
|
||||
+++ b/fs/exofs/ore_raid.c
|
||||
@@ -328,8 +328,8 @@ static int _alloc_read_4_write(struct ore_io_state *ios)
|
||||
/* @si contains info of the to-be-inserted page. Update of @si should be
|
||||
* maintained by caller. Specificaly si->dev, si->obj_offset, ...
|
||||
*/
|
||||
-static int _add_to_read_4_write(struct ore_io_state *ios,
|
||||
- struct ore_striping_info *si, struct page *page)
|
||||
+static int _add_to_r4w(struct ore_io_state *ios, struct ore_striping_info *si,
|
||||
+ struct page *page, unsigned pg_len)
|
||||
{
|
||||
struct request_queue *q;
|
||||
struct ore_per_dev_state *per_dev;
|
||||
@@ -366,17 +366,60 @@ static int _add_to_read_4_write(struct ore_io_state *ios,
|
||||
_ore_add_sg_seg(per_dev, gap, true);
|
||||
}
|
||||
q = osd_request_queue(ore_comp_dev(read_ios->oc, per_dev->dev));
|
||||
- added_len = bio_add_pc_page(q, per_dev->bio, page, PAGE_SIZE, 0);
|
||||
- if (unlikely(added_len != PAGE_SIZE)) {
|
||||
+ added_len = bio_add_pc_page(q, per_dev->bio, page, pg_len,
|
||||
+ si->obj_offset % PAGE_SIZE);
|
||||
+ if (unlikely(added_len != pg_len)) {
|
||||
ORE_DBGMSG("Failed to bio_add_pc_page bi_vcnt=%d\n",
|
||||
per_dev->bio->bi_vcnt);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
- per_dev->length += PAGE_SIZE;
|
||||
+ per_dev->length += pg_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* read the beginning of an unaligned first page */
|
||||
+static int _add_to_r4w_first_page(struct ore_io_state *ios, struct page *page)
|
||||
+{
|
||||
+ struct ore_striping_info si;
|
||||
+ unsigned pg_len;
|
||||
+
|
||||
+ ore_calc_stripe_info(ios->layout, ios->offset, 0, &si);
|
||||
+
|
||||
+ pg_len = si.obj_offset % PAGE_SIZE;
|
||||
+ si.obj_offset -= pg_len;
|
||||
+
|
||||
+ ORE_DBGMSG("offset=0x%llx len=0x%x index=0x%lx dev=%x\n",
|
||||
+ _LLU(si.obj_offset), pg_len, page->index, si.dev);
|
||||
+
|
||||
+ return _add_to_r4w(ios, &si, page, pg_len);
|
||||
+}
|
||||
+
|
||||
+/* read the end of an incomplete last page */
|
||||
+static int _add_to_r4w_last_page(struct ore_io_state *ios, u64 *offset)
|
||||
+{
|
||||
+ struct ore_striping_info si;
|
||||
+ struct page *page;
|
||||
+ unsigned pg_len, p, c;
|
||||
+
|
||||
+ ore_calc_stripe_info(ios->layout, *offset, 0, &si);
|
||||
+
|
||||
+ p = si.unit_off / PAGE_SIZE;
|
||||
+ c = _dev_order(ios->layout->group_width * ios->layout->mirrors_p1,
|
||||
+ ios->layout->mirrors_p1, si.par_dev, si.dev);
|
||||
+ page = ios->sp2d->_1p_stripes[p].pages[c];
|
||||
+
|
||||
+ pg_len = PAGE_SIZE - (si.unit_off % PAGE_SIZE);
|
||||
+ *offset += pg_len;
|
||||
+
|
||||
+ ORE_DBGMSG("p=%d, c=%d next-offset=0x%llx len=0x%x dev=%x par_dev=%d\n",
|
||||
+ p, c, _LLU(*offset), pg_len, si.dev, si.par_dev);
|
||||
+
|
||||
+ BUG_ON(!page);
|
||||
+
|
||||
+ return _add_to_r4w(ios, &si, page, pg_len);
|
||||
+}
|
||||
+
|
||||
static void _mark_read4write_pages_uptodate(struct ore_io_state *ios, int ret)
|
||||
{
|
||||
struct bio_vec *bv;
|
||||
@@ -444,9 +487,13 @@ static int _read_4_write(struct ore_io_state *ios)
|
||||
struct page **pp = &_1ps->pages[c];
|
||||
bool uptodate;
|
||||
|
||||
- if (*pp)
|
||||
+ if (*pp) {
|
||||
+ if (ios->offset % PAGE_SIZE)
|
||||
+ /* Read the remainder of the page */
|
||||
+ _add_to_r4w_first_page(ios, *pp);
|
||||
/* to-be-written pages start here */
|
||||
goto read_last_stripe;
|
||||
+ }
|
||||
|
||||
*pp = ios->r4w->get_page(ios->private, offset,
|
||||
&uptodate);
|
||||
@@ -454,7 +501,7 @@ static int _read_4_write(struct ore_io_state *ios)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!uptodate)
|
||||
- _add_to_read_4_write(ios, &read_si, *pp);
|
||||
+ _add_to_r4w(ios, &read_si, *pp, PAGE_SIZE);
|
||||
|
||||
/* Mark read-pages to be cache_released */
|
||||
_1ps->page_is_read[c] = true;
|
||||
@@ -465,8 +512,11 @@ static int _read_4_write(struct ore_io_state *ios)
|
||||
}
|
||||
|
||||
read_last_stripe:
|
||||
- offset = ios->offset + (ios->length + PAGE_SIZE - 1) /
|
||||
- PAGE_SIZE * PAGE_SIZE;
|
||||
+ offset = ios->offset + ios->length;
|
||||
+ if (offset % PAGE_SIZE)
|
||||
+ _add_to_r4w_last_page(ios, &offset);
|
||||
+ /* offset will be aligned to next page */
|
||||
+
|
||||
last_stripe_end = div_u64(offset + bytes_in_stripe - 1, bytes_in_stripe)
|
||||
* bytes_in_stripe;
|
||||
if (offset == last_stripe_end) /* Optimize for the aligned case */
|
||||
@@ -503,7 +553,7 @@ read_last_stripe:
|
||||
/* Mark read-pages to be cache_released */
|
||||
_1ps->page_is_read[c] = true;
|
||||
if (!uptodate)
|
||||
- _add_to_read_4_write(ios, &read_si, page);
|
||||
+ _add_to_r4w(ios, &read_si, page, PAGE_SIZE);
|
||||
}
|
||||
|
||||
offset += PAGE_SIZE;
|
||||
@@ -616,8 +666,6 @@ int _ore_post_alloc_raid_stuff(struct ore_io_state *ios)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
- BUG_ON(ios->offset % PAGE_SIZE);
|
||||
-
|
||||
/* Round io down to last full strip */
|
||||
first_stripe = div_u64(ios->offset, stripe_size);
|
||||
last_stripe = div_u64(ios->offset + ios->length, stripe_size);
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
From db0889eb6584510c3e1d860bfcfc7a85efc6fabe Mon Sep 17 00:00:00 2001
|
||||
From: Boaz Harrosh <bharrosh@panasas.com>
|
||||
Date: Tue, 29 Nov 2011 15:35:53 -0800
|
||||
Subject: [PATCH 22/49] ore: FIX breakage when MISC_FILESYSTEMS is not set
|
||||
|
||||
commit 831c2dc5f47c1dc79c32229d75065ada1dcc66e1 upstream.
|
||||
|
||||
As Reported by Randy Dunlap
|
||||
|
||||
When MISC_FILESYSTEMS is not enabled and NFS4.1 is:
|
||||
|
||||
fs/built-in.o: In function `objio_alloc_io_state':
|
||||
objio_osd.c:(.text+0xcb525): undefined reference to `ore_get_rw_state'
|
||||
fs/built-in.o: In function `_write_done':
|
||||
objio_osd.c:(.text+0xcb58d): undefined reference to `ore_check_io'
|
||||
fs/built-in.o: In function `_read_done':
|
||||
...
|
||||
|
||||
When MISC_FILESYSTEMS, which is more of a GUI thing then anything else,
|
||||
is not selected. exofs/Kconfig is never examined during Kconfig,
|
||||
and it can not do it's magic stuff to automatically select everything
|
||||
needed.
|
||||
|
||||
We must split exofs/Kconfig in two. The ore one is always included.
|
||||
And the exofs one is left in it's old place in the menu.
|
||||
|
||||
Reported-by: Randy Dunlap <rdunlap@xenotime.net>
|
||||
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
fs/Kconfig | 2 ++
|
||||
fs/exofs/Kconfig | 11 -----------
|
||||
fs/exofs/Kconfig.ore | 12 ++++++++++++
|
||||
3 files changed, 14 insertions(+), 11 deletions(-)
|
||||
create mode 100644 fs/exofs/Kconfig.ore
|
||||
|
||||
diff --git a/fs/Kconfig b/fs/Kconfig
|
||||
index 5f4c45d..6ad58a5 100644
|
||||
--- a/fs/Kconfig
|
||||
+++ b/fs/Kconfig
|
||||
@@ -218,6 +218,8 @@ source "fs/exofs/Kconfig"
|
||||
|
||||
endif # MISC_FILESYSTEMS
|
||||
|
||||
+source "fs/exofs/Kconfig.ore"
|
||||
+
|
||||
menuconfig NETWORK_FILESYSTEMS
|
||||
bool "Network File Systems"
|
||||
default y
|
||||
diff --git a/fs/exofs/Kconfig b/fs/exofs/Kconfig
|
||||
index da42f32..86194b2 100644
|
||||
--- a/fs/exofs/Kconfig
|
||||
+++ b/fs/exofs/Kconfig
|
||||
@@ -1,14 +1,3 @@
|
||||
-# Note ORE needs to "select ASYNC_XOR". So Not to force multiple selects
|
||||
-# for every ORE user we do it like this. Any user should add itself here
|
||||
-# at the "depends on EXOFS_FS || ..." with an ||. The dependencies are
|
||||
-# selected here, and we default to "ON". So in effect it is like been
|
||||
-# selected by any of the users.
|
||||
-config ORE
|
||||
- tristate
|
||||
- depends on EXOFS_FS || PNFS_OBJLAYOUT
|
||||
- select ASYNC_XOR
|
||||
- default SCSI_OSD_ULD
|
||||
-
|
||||
config EXOFS_FS
|
||||
tristate "exofs: OSD based file system support"
|
||||
depends on SCSI_OSD_ULD
|
||||
diff --git a/fs/exofs/Kconfig.ore b/fs/exofs/Kconfig.ore
|
||||
new file mode 100644
|
||||
index 0000000..1ca7fb7
|
||||
--- /dev/null
|
||||
+++ b/fs/exofs/Kconfig.ore
|
||||
@@ -0,0 +1,12 @@
|
||||
+# ORE - Objects Raid Engine (libore.ko)
|
||||
+#
|
||||
+# Note ORE needs to "select ASYNC_XOR". So Not to force multiple selects
|
||||
+# for every ORE user we do it like this. Any user should add itself here
|
||||
+# at the "depends on EXOFS_FS || ..." with an ||. The dependencies are
|
||||
+# selected here, and we default to "ON". So in effect it is like been
|
||||
+# selected by any of the users.
|
||||
+config ORE
|
||||
+ tristate
|
||||
+ depends on EXOFS_FS || PNFS_OBJLAYOUT
|
||||
+ select ASYNC_XOR
|
||||
+ default SCSI_OSD_ULD
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
From 914681dc085b7bdeae0de64fba94532a6bcd093e Mon Sep 17 00:00:00 2001
|
||||
From: Jan Kara <jack@suse.cz>
|
||||
Date: Wed, 21 Dec 2011 17:35:34 +0100
|
||||
Subject: [PATCH 23/49] reiserfs: Fix quota mount option parsing
|
||||
|
||||
commit a06d789b424190e9f59da391681f908486db2554 upstream.
|
||||
|
||||
When jqfmt mount option is not specified on remount, we mistakenly clear
|
||||
s_jquota_fmt value stored in superblock. Fix the problem.
|
||||
|
||||
CC: reiserfs-devel@vger.kernel.org
|
||||
Signed-off-by: Jan Kara <jack@suse.cz>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
fs/reiserfs/super.c | 3 ++-
|
||||
1 files changed, 2 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
|
||||
index 14363b9..f9eaa4a 100644
|
||||
--- a/fs/reiserfs/super.c
|
||||
+++ b/fs/reiserfs/super.c
|
||||
@@ -1164,7 +1164,8 @@ static void handle_quota_files(struct super_block *s, char **qf_names,
|
||||
kfree(REISERFS_SB(s)->s_qf_names[i]);
|
||||
REISERFS_SB(s)->s_qf_names[i] = qf_names[i];
|
||||
}
|
||||
- REISERFS_SB(s)->s_jquota_fmt = *qfmt;
|
||||
+ if (*qfmt)
|
||||
+ REISERFS_SB(s)->s_jquota_fmt = *qfmt;
|
||||
}
|
||||
#endif
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
From 0621050323cd3eef6fe27f168151e8823a6f63dd Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Mahoney <jeffm@suse.com>
|
||||
Date: Wed, 21 Dec 2011 21:18:43 +0100
|
||||
Subject: [PATCH 24/49] reiserfs: Force inode evictions before umount to avoid
|
||||
crash
|
||||
|
||||
commit a9e36da655e54545c3289b2a0700b5c443de0edd upstream.
|
||||
|
||||
This patch fixes a crash in reiserfs_delete_xattrs during umount.
|
||||
|
||||
When shrink_dcache_for_umount clears the dcache from
|
||||
generic_shutdown_super, delayed evictions are forced to disk. If an
|
||||
evicted inode has extended attributes associated with it, it will
|
||||
need to walk the xattr tree to locate and remove them.
|
||||
|
||||
But since shrink_dcache_for_umount will BUG if it encounters active
|
||||
dentries, the xattr tree must be released before it's called or it will
|
||||
crash during every umount.
|
||||
|
||||
This patch forces the evictions to occur before generic_shutdown_super
|
||||
by calling shrink_dcache_sb first. The additional evictions caused
|
||||
by the removal of each associated xattr file and dir will be automatically
|
||||
handled as they're added to the LRU list.
|
||||
|
||||
CC: reiserfs-devel@vger.kernel.org
|
||||
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
|
||||
Signed-off-by: Jan Kara <jack@suse.cz>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
fs/reiserfs/super.c | 24 ++++++++++++++----------
|
||||
1 files changed, 14 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
|
||||
index f9eaa4a..5e3527b 100644
|
||||
--- a/fs/reiserfs/super.c
|
||||
+++ b/fs/reiserfs/super.c
|
||||
@@ -453,16 +453,20 @@ int remove_save_link(struct inode *inode, int truncate)
|
||||
static void reiserfs_kill_sb(struct super_block *s)
|
||||
{
|
||||
if (REISERFS_SB(s)) {
|
||||
- if (REISERFS_SB(s)->xattr_root) {
|
||||
- d_invalidate(REISERFS_SB(s)->xattr_root);
|
||||
- dput(REISERFS_SB(s)->xattr_root);
|
||||
- REISERFS_SB(s)->xattr_root = NULL;
|
||||
- }
|
||||
- if (REISERFS_SB(s)->priv_root) {
|
||||
- d_invalidate(REISERFS_SB(s)->priv_root);
|
||||
- dput(REISERFS_SB(s)->priv_root);
|
||||
- REISERFS_SB(s)->priv_root = NULL;
|
||||
- }
|
||||
+ /*
|
||||
+ * Force any pending inode evictions to occur now. Any
|
||||
+ * inodes to be removed that have extended attributes
|
||||
+ * associated with them need to clean them up before
|
||||
+ * we can release the extended attribute root dentries.
|
||||
+ * shrink_dcache_for_umount will BUG if we don't release
|
||||
+ * those before it's called so ->put_super is too late.
|
||||
+ */
|
||||
+ shrink_dcache_sb(s);
|
||||
+
|
||||
+ dput(REISERFS_SB(s)->xattr_root);
|
||||
+ REISERFS_SB(s)->xattr_root = NULL;
|
||||
+ dput(REISERFS_SB(s)->priv_root);
|
||||
+ REISERFS_SB(s)->priv_root = NULL;
|
||||
}
|
||||
|
||||
kill_block_super(s);
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
From d6bc098d6daabceca79a299bfe95dfe218661423 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Kara <jack@suse.cz>
|
||||
Date: Thu, 22 Dec 2011 16:49:05 +0100
|
||||
Subject: [PATCH 25/49] ext3: Don't warn from writepage when readonly inode is
|
||||
spotted after error
|
||||
|
||||
commit 33c104d415e92a51aaf638dc3d93920cfa601e5c upstream.
|
||||
|
||||
WARN_ON_ONCE(IS_RDONLY(inode)) tends to trip when filesystem hits error and is
|
||||
remounted read-only. This unnecessarily scares users (well, they should be
|
||||
scared because of filesystem error, but the stack trace distracts them from the
|
||||
right source of their fear ;-). We could as well just remove the WARN_ON but
|
||||
it's not hard to fix it to not trip on filesystem with errors and not use more
|
||||
cycles in the common case so that's what we do.
|
||||
|
||||
Signed-off-by: Jan Kara <jack@suse.cz>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
fs/ext3/inode.c | 24 +++++++++++++++++++++---
|
||||
1 files changed, 21 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
|
||||
index 85fe655..5b3f907 100644
|
||||
--- a/fs/ext3/inode.c
|
||||
+++ b/fs/ext3/inode.c
|
||||
@@ -1617,7 +1617,13 @@ static int ext3_ordered_writepage(struct page *page,
|
||||
int err;
|
||||
|
||||
J_ASSERT(PageLocked(page));
|
||||
- WARN_ON_ONCE(IS_RDONLY(inode));
|
||||
+ /*
|
||||
+ * We don't want to warn for emergency remount. The condition is
|
||||
+ * ordered to avoid dereferencing inode->i_sb in non-error case to
|
||||
+ * avoid slow-downs.
|
||||
+ */
|
||||
+ WARN_ON_ONCE(IS_RDONLY(inode) &&
|
||||
+ !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ERROR_FS));
|
||||
|
||||
/*
|
||||
* We give up here if we're reentered, because it might be for a
|
||||
@@ -1692,7 +1698,13 @@ static int ext3_writeback_writepage(struct page *page,
|
||||
int err;
|
||||
|
||||
J_ASSERT(PageLocked(page));
|
||||
- WARN_ON_ONCE(IS_RDONLY(inode));
|
||||
+ /*
|
||||
+ * We don't want to warn for emergency remount. The condition is
|
||||
+ * ordered to avoid dereferencing inode->i_sb in non-error case to
|
||||
+ * avoid slow-downs.
|
||||
+ */
|
||||
+ WARN_ON_ONCE(IS_RDONLY(inode) &&
|
||||
+ !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ERROR_FS));
|
||||
|
||||
if (ext3_journal_current_handle())
|
||||
goto out_fail;
|
||||
@@ -1735,7 +1747,13 @@ static int ext3_journalled_writepage(struct page *page,
|
||||
int err;
|
||||
|
||||
J_ASSERT(PageLocked(page));
|
||||
- WARN_ON_ONCE(IS_RDONLY(inode));
|
||||
+ /*
|
||||
+ * We don't want to warn for emergency remount. The condition is
|
||||
+ * ordered to avoid dereferencing inode->i_sb in non-error case to
|
||||
+ * avoid slow-downs.
|
||||
+ */
|
||||
+ WARN_ON_ONCE(IS_RDONLY(inode) &&
|
||||
+ !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ERROR_FS));
|
||||
|
||||
if (ext3_journal_current_handle())
|
||||
goto no_write;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
From b9e6c637b69ffe81b7f272f433f18e3cd2f58052 Mon Sep 17 00:00:00 2001
|
||||
From: "K. Y. Srinivasan" <kys@microsoft.com>
|
||||
Date: Thu, 1 Dec 2011 09:59:34 -0800
|
||||
Subject: [PATCH 26/49] drivers: hv: Don't OOPS when you cannot init vmbus
|
||||
|
||||
commit cf6a2eacbcb2593b5b91d0817915c4f0464bb534 upstream.
|
||||
|
||||
The hv vmbus driver was causing an OOPS since it was trying to register drivers
|
||||
on top of the bus even if initialization of the bus has failed for some
|
||||
reason (such as the odd chance someone would run a hv enabled kernel in a
|
||||
non-hv environment).
|
||||
|
||||
Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/hv/vmbus_drv.c | 16 ++++++++++++++++
|
||||
1 files changed, 16 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
|
||||
index 0c048dd..d3b0b4f 100644
|
||||
--- a/drivers/hv/vmbus_drv.c
|
||||
+++ b/drivers/hv/vmbus_drv.c
|
||||
@@ -62,6 +62,14 @@ struct hv_device_info {
|
||||
struct hv_dev_port_info outbound;
|
||||
};
|
||||
|
||||
+static int vmbus_exists(void)
|
||||
+{
|
||||
+ if (hv_acpi_dev == NULL)
|
||||
+ return -ENODEV;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
|
||||
static void get_channel_info(struct hv_device *device,
|
||||
struct hv_device_info *info)
|
||||
@@ -590,6 +598,10 @@ int __vmbus_driver_register(struct hv_driver *hv_driver, struct module *owner, c
|
||||
|
||||
pr_info("registering driver %s\n", hv_driver->name);
|
||||
|
||||
+ ret = vmbus_exists();
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
hv_driver->driver.name = hv_driver->name;
|
||||
hv_driver->driver.owner = owner;
|
||||
hv_driver->driver.mod_name = mod_name;
|
||||
@@ -614,6 +626,9 @@ void vmbus_driver_unregister(struct hv_driver *hv_driver)
|
||||
{
|
||||
pr_info("unregistering driver %s\n", hv_driver->name);
|
||||
|
||||
+ if (!vmbus_exists())
|
||||
+ return;
|
||||
+
|
||||
driver_unregister(&hv_driver->driver);
|
||||
|
||||
}
|
||||
@@ -776,6 +791,7 @@ static int __init hv_acpi_init(void)
|
||||
|
||||
cleanup:
|
||||
acpi_bus_unregister_driver(&vmbus_acpi_driver);
|
||||
+ hv_acpi_dev = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
From 797931db7094985a8aa99b24695192d1773129de Mon Sep 17 00:00:00 2001
|
||||
From: "K. Y. Srinivasan" <kys@microsoft.com>
|
||||
Date: Tue, 27 Dec 2011 13:49:37 -0800
|
||||
Subject: [PATCH 27/49] Drivers:hv: Fix a bug in vmbus_driver_unregister()
|
||||
|
||||
commit 8f257a142fc3868d69de3f996b95d7bdbc509560 upstream.
|
||||
|
||||
The function vmbus_exists() was introduced recently to deal with cases where
|
||||
the vmbus driver failed to initialize and yet other Hyper-V drivers attempted
|
||||
to register with the vmbus bus driver. This patch introduced a bug where
|
||||
vmbus_driver_unregister() would fail to unregister the driver. This patch
|
||||
fixes the problem.
|
||||
|
||||
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Signed-off-by: Fuzhou Chen <fuzhouch@microsoft.com>
|
||||
Cc: Sasha Levin <levinsasha928@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/hv/vmbus_drv.c | 5 +----
|
||||
1 files changed, 1 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
|
||||
index d3b0b4f..d2d0a2a 100644
|
||||
--- a/drivers/hv/vmbus_drv.c
|
||||
+++ b/drivers/hv/vmbus_drv.c
|
||||
@@ -627,10 +627,7 @@ void vmbus_driver_unregister(struct hv_driver *hv_driver)
|
||||
pr_info("unregistering driver %s\n", hv_driver->name);
|
||||
|
||||
if (!vmbus_exists())
|
||||
- return;
|
||||
-
|
||||
- driver_unregister(&hv_driver->driver);
|
||||
-
|
||||
+ driver_unregister(&hv_driver->driver);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vmbus_driver_unregister);
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
From a4d5730e9c4b209e74eab2f7650b23f95417dc71 Mon Sep 17 00:00:00 2001
|
||||
From: Alan Stern <stern@rowland.harvard.edu>
|
||||
Date: Wed, 4 Jan 2012 16:36:35 -0500
|
||||
Subject: [PATCH 28/49] USB: update documentation for usbmon
|
||||
|
||||
commit d8cae98cddd286e38db1724dda1b0e7b467f9237 upstream.
|
||||
|
||||
The documentation for usbmon is out of date; the usbfs "devices" file
|
||||
now exists in /sys/kernel/debug/usb rather than /proc/bus/usb. This
|
||||
patch (as1505) updates the documentation accordingly, and also
|
||||
mentions that the necessary information can be found by running lsusb.
|
||||
|
||||
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
|
||||
CC: Pete Zaitcev <zaitcev@redhat.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
Documentation/usb/usbmon.txt | 14 +++++++++-----
|
||||
1 files changed, 9 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/Documentation/usb/usbmon.txt b/Documentation/usb/usbmon.txt
|
||||
index a4efa04..5335fa8 100644
|
||||
--- a/Documentation/usb/usbmon.txt
|
||||
+++ b/Documentation/usb/usbmon.txt
|
||||
@@ -47,10 +47,11 @@ This allows to filter away annoying devices that talk continuously.
|
||||
|
||||
2. Find which bus connects to the desired device
|
||||
|
||||
-Run "cat /proc/bus/usb/devices", and find the T-line which corresponds to
|
||||
-the device. Usually you do it by looking for the vendor string. If you have
|
||||
-many similar devices, unplug one and compare two /proc/bus/usb/devices outputs.
|
||||
-The T-line will have a bus number. Example:
|
||||
+Run "cat /sys/kernel/debug/usb/devices", and find the T-line which corresponds
|
||||
+to the device. Usually you do it by looking for the vendor string. If you have
|
||||
+many similar devices, unplug one and compare the two
|
||||
+/sys/kernel/debug/usb/devices outputs. The T-line will have a bus number.
|
||||
+Example:
|
||||
|
||||
T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0
|
||||
D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
|
||||
@@ -58,7 +59,10 @@ P: Vendor=0557 ProdID=2004 Rev= 1.00
|
||||
S: Manufacturer=ATEN
|
||||
S: Product=UC100KM V2.00
|
||||
|
||||
-Bus=03 means it's bus 3.
|
||||
+"Bus=03" means it's bus 3. Alternatively, you can look at the output from
|
||||
+"lsusb" and get the bus number from the appropriate line. Example:
|
||||
+
|
||||
+Bus 003 Device 002: ID 0557:2004 ATEN UC100KM V2.00
|
||||
|
||||
3. Start 'cat'
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
From 6b544616a14b48a670d0c7ce10a5f8de1246cc96 Mon Sep 17 00:00:00 2001
|
||||
From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
|
||||
Date: Fri, 16 Dec 2011 11:26:30 -0800
|
||||
Subject: [PATCH 29/49] usbfs: Fix oops related to user namespace conversion.
|
||||
|
||||
commit 1b41c8321e495337e877ca02d0b9680bc4112eff upstream.
|
||||
|
||||
When running the Point Grey "flycap" program for their USB 3.0 camera
|
||||
(which was running as a USB 2.0 device for some reason), I trigger this
|
||||
oops whenever I try to open a video stream:
|
||||
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.715559] BUG: unable to handle kernel NULL pointer dereference at (null)
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.719153] IP: [<ffffffff8147841e>] free_async+0x1e/0x70
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.720991] PGD 6f833067 PUD 6fc56067 PMD 0
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.722815] Oops: 0002 [#1] SMP
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.724627] CPU 0
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.724636] Modules linked in: ecryptfs encrypted_keys sha1_generic trusted binfmt_misc sha256_generic aesni_intel cryptd aes_x86_64 aes_generic parport_pc dm_crypt ppdev joydev snd_hda_codec_hdmi snd_hda_codec_conexant arc4 iwlwifi snd_hda_intel snd_hda_codec snd_hwdep snd_pcm thinkpad_acpi mac80211 snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq snd_timer btusb uvcvideo snd_seq_device bluetooth videodev psmouse snd v4l2_compat_ioctl32 serio_raw tpm_tis cfg80211 tpm tpm_bios nvram soundcore snd_page_alloc lp parport i915 xhci_hcd ahci libahci drm_kms_helper drm sdhci_pci sdhci e1000e i2c_algo_bit video
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.734212]
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.736162] Pid: 2713, comm: FlyCap2 Not tainted 3.2.0-rc5+ #28 LENOVO 4286CTO/4286CTO
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.738148] RIP: 0010:[<ffffffff8147841e>] [<ffffffff8147841e>] free_async+0x1e/0x70
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.740134] RSP: 0018:ffff88005715fd78 EFLAGS: 00010296
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.742118] RAX: 00000000fffffff4 RBX: ffff88006fe8f900 RCX: 0000000000004118
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.744116] RDX: 0000000001000000 RSI: 0000000000016390 RDI: 0000000000000000
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.746087] RBP: ffff88005715fd88 R08: 0000000000000000 R09: ffffffff8146f22e
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.748018] R10: ffff88006e520ac0 R11: 0000000000000001 R12: ffff88005715fe28
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.749916] R13: ffff88005d31df00 R14: ffff88006fe8f900 R15: 00007f688c995cb8
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.751785] FS: 00007f68a366da40(0000) GS:ffff880100200000(0000) knlGS:0000000000000000
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.753659] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.755509] CR2: 0000000000000000 CR3: 00000000706bb000 CR4: 00000000000406f0
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.757334] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.759124] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.760871] Process FlyCap2 (pid: 2713, threadinfo ffff88005715e000, task ffff88006c675b80)
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.762605] Stack:
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.764297] ffff88005715fe28 0000000000000000 ffff88005715fe08 ffffffff81479058
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.766020] 0000000000000000 ffffea0000004000 ffff880000004118 0000000000000000
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.767750] ffff880000000001 ffff88006e520ac0 fffffff46fd81180 0000000000000000
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.769472] Call Trace:
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.771147] [<ffffffff81479058>] proc_do_submiturb+0x778/0xa00
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.772798] [<ffffffff8147a5fd>] usbdev_do_ioctl+0x24d/0x1200
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.774410] [<ffffffff8147b5de>] usbdev_ioctl+0xe/0x20
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.775975] [<ffffffff81189259>] do_vfs_ioctl+0x99/0x600
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.777534] [<ffffffff81189851>] sys_ioctl+0x91/0xa0
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.779088] [<ffffffff816247c2>] system_call_fastpath+0x16/0x1b
|
||||
ec 15 16:48:34 puck kernel: [ 1798.780634] Code: 51 ff ff ff e9 29 ff ff ff 0f 1f 40 00 55 48 89 e5 53 48 83 ec 08 66 66 66 66 90 48 89 fb 48 8b 7f 18 e8 a6 ea c0 ff 4
|
||||
8 8b 7b 20 <f0> ff 0f 0f 94 c0 84 c0 74 05 e8 d3 99 c1 ff 48 8b 43 40 48 8b
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.783970] RIP [<ffffffff8147841e>] free_async+0x1e/0x70
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.785630] RSP <ffff88005715fd78>
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.787274] CR2: 0000000000000000
|
||||
Dec 15 16:48:34 puck kernel: [ 1798.794728] ---[ end trace 52894d3355f88d19 ]---
|
||||
|
||||
markup_oops.pl says the oops is in put_cred:
|
||||
|
||||
ffffffff81478401: 48 89 e5 mov %rsp,%rbp
|
||||
ffffffff81478404: 53 push %rbx
|
||||
ffffffff81478405: 48 83 ec 08 sub $0x8,%rsp
|
||||
ffffffff81478409: e8 f2 c0 1a 00 callq ffffffff81624500 <mcount>
|
||||
ffffffff8147840e: 48 89 fb mov %rdi,%rbx | %ebx => ffff88006fe8f900
|
||||
put_pid(as->pid);
|
||||
ffffffff81478411: 48 8b 7f 18 mov 0x18(%rdi),%rdi
|
||||
ffffffff81478415: e8 a6 ea c0 ff callq ffffffff81086ec0 <put_pid>
|
||||
put_cred(as->cred);
|
||||
ffffffff8147841a: 48 8b 7b 20 mov 0x20(%rbx),%rdi | %edi => 0 %ebx = ffff88006fe8f900
|
||||
*/
|
||||
static inline int atomic_dec_and_test(atomic_t *v)
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
asm volatile(LOCK_PREFIX "decl %0; sete %1"
|
||||
*ffffffff8147841e: f0 ff 0f lock decl (%rdi) | %edi = 0 <--- faulting instruction
|
||||
ffffffff81478421: 0f 94 c0 sete %al
|
||||
static inline void put_cred(const struct cred *_cred)
|
||||
{
|
||||
struct cred *cred = (struct cred *) _cred;
|
||||
|
||||
validate_creds(cred);
|
||||
if (atomic_dec_and_test(&(cred)->usage))
|
||||
ffffffff81478424: 84 c0 test %al,%al
|
||||
ffffffff81478426: 74 05 je ffffffff8147842d <free_async+0x2d>
|
||||
__put_cred(cred);
|
||||
ffffffff81478428: e8 d3 99 c1 ff callq ffffffff81091e00 <__put_cred>
|
||||
kfree(as->urb->transfer_buffer);
|
||||
ffffffff8147842d: 48 8b 43 40 mov 0x40(%rbx),%rax
|
||||
ffffffff81478431: 48 8b 78 68 mov 0x68(%rax),%rdi
|
||||
ffffffff81478435: e8 a6 e1 ce ff callq ffffffff811665e0 <kfree>
|
||||
kfree(as->urb->setup_packet);
|
||||
ffffffff8147843a: 48 8b 43 40 mov 0x40(%rbx),%rax
|
||||
ffffffff8147843e: 48 8b b8 90 00 00 00 mov 0x90(%rax),%rdi
|
||||
ffffffff81478445: e8 96 e1 ce ff callq ffffffff811665e0 <kfree>
|
||||
usb_free_urb(as->urb);
|
||||
ffffffff8147844a: 48 8b 7b 40 mov 0x40(%rbx),%rdi
|
||||
ffffffff8147844e: e8 0d 6b ff ff callq ffffffff8146ef60 <usb_free_urb>
|
||||
|
||||
This bug seems to have been introduced by commit
|
||||
d178bc3a708f39cbfefc3fab37032d3f2511b4ec "user namespace: usb: make usb
|
||||
urbs user namespace aware (v2)"
|
||||
|
||||
I'm not sure if this is right fix, but it does stop the oops.
|
||||
|
||||
Unfortunately, the Point Grey software still refuses to work, but it's a
|
||||
closed source app, so I can't fix it.
|
||||
|
||||
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
|
||||
Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/usb/core/devio.c | 3 ++-
|
||||
1 files changed, 2 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
|
||||
index e3beaf2..7abf060 100644
|
||||
--- a/drivers/usb/core/devio.c
|
||||
+++ b/drivers/usb/core/devio.c
|
||||
@@ -249,7 +249,8 @@ static struct async *alloc_async(unsigned int numisoframes)
|
||||
static void free_async(struct async *as)
|
||||
{
|
||||
put_pid(as->pid);
|
||||
- put_cred(as->cred);
|
||||
+ if (as->cred)
|
||||
+ put_cred(as->cred);
|
||||
kfree(as->urb->transfer_buffer);
|
||||
kfree(as->urb->setup_packet);
|
||||
usb_free_urb(as->urb);
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
From 2918b666fe0636d9d90ce6defda2d3ec908231a8 Mon Sep 17 00:00:00 2001
|
||||
From: Claudio Scordino <claudio@evidence.eu.com>
|
||||
Date: Fri, 16 Dec 2011 15:08:49 +0100
|
||||
Subject: [PATCH 30/49] atmel_serial: fix spinlock lockup in RS485 code
|
||||
|
||||
commit dbf1115d3f8c7052788aa4e6e46abd27f3b3eeba upstream.
|
||||
|
||||
Patch to fix a spinlock lockup in the driver that sometimes happens when the
|
||||
tasklet starts.
|
||||
|
||||
Signed-off-by: Claudio Scordino <claudio@evidence.eu.com>
|
||||
Signed-off-by: Dave Bender <codehero@gmail.com>
|
||||
Tested-by: Dave Bender <codehero@gmail.com>
|
||||
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
|
||||
Acked-by: Alan Cox <alan@linux.intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/tty/serial/atmel_serial.c | 5 +++--
|
||||
1 files changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
|
||||
index 4c823f3..90c8e3a 100644
|
||||
--- a/drivers/tty/serial/atmel_serial.c
|
||||
+++ b/drivers/tty/serial/atmel_serial.c
|
||||
@@ -212,8 +212,9 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf)
|
||||
{
|
||||
struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
|
||||
unsigned int mode;
|
||||
+ unsigned long flags;
|
||||
|
||||
- spin_lock(&port->lock);
|
||||
+ spin_lock_irqsave(&port->lock, flags);
|
||||
|
||||
/* Disable interrupts */
|
||||
UART_PUT_IDR(port, atmel_port->tx_done_mask);
|
||||
@@ -244,7 +245,7 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf)
|
||||
/* Enable interrupts */
|
||||
UART_PUT_IER(port, atmel_port->tx_done_mask);
|
||||
|
||||
- spin_unlock(&port->lock);
|
||||
+ spin_unlock_irqrestore(&port->lock, flags);
|
||||
|
||||
}
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
From 7e755f9707e34e7de22e2f3b77ab26d1d8de5a4b Mon Sep 17 00:00:00 2001
|
||||
From: Li Zefan <lizf@cn.fujitsu.com>
|
||||
Date: Tue, 27 Dec 2011 14:25:55 +0800
|
||||
Subject: [PATCH 31/49] cgroup: fix to allow mounting a hierarchy by name
|
||||
|
||||
commit 0d19ea866562e46989412a0676412fa0983c9ce7 upstream.
|
||||
|
||||
If we mount a hierarchy with a specified name, the name is unique,
|
||||
and we can use it to mount the hierarchy without specifying its
|
||||
set of subsystem names. This feature is documented is
|
||||
Documentation/cgroups/cgroups.txt section 2.3
|
||||
|
||||
Here's an example:
|
||||
|
||||
# mount -t cgroup -o cpuset,name=myhier xxx /cgroup1
|
||||
# mount -t cgroup -o name=myhier xxx /cgroup2
|
||||
|
||||
But it was broken by commit 32a8cf235e2f192eb002755076994525cdbaa35a
|
||||
(cgroup: make the mount options parsing more accurate)
|
||||
|
||||
This fixes the regression.
|
||||
|
||||
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
|
||||
Signed-off-by: Tejun Heo <tj@kernel.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
kernel/cgroup.c | 6 +++---
|
||||
1 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
|
||||
index a184470..cdc0354 100644
|
||||
--- a/kernel/cgroup.c
|
||||
+++ b/kernel/cgroup.c
|
||||
@@ -1175,10 +1175,10 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts)
|
||||
|
||||
/*
|
||||
* If the 'all' option was specified select all the subsystems,
|
||||
- * otherwise 'all, 'none' and a subsystem name options were not
|
||||
- * specified, let's default to 'all'
|
||||
+ * otherwise if 'none', 'name=' and a subsystem name options
|
||||
+ * were not specified, let's default to 'all'
|
||||
*/
|
||||
- if (all_ss || (!all_ss && !one_ss && !opts->none)) {
|
||||
+ if (all_ss || (!one_ss && !opts->none && !opts->name)) {
|
||||
for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
|
||||
struct cgroup_subsys *ss = subsys[i];
|
||||
if (ss == NULL)
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
From b2b56aa7932508ce3a81187a68e6a558268efc35 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Kara <jack@suse.cz>
|
||||
Date: Sat, 10 Dec 2011 02:30:48 +0100
|
||||
Subject: [PATCH 32/49] udf: Fix deadlock when converting file from in-ICB one
|
||||
to normal one
|
||||
|
||||
commit d2eb8c359309ec45d6bf5b147303ab8e13be86ea upstream.
|
||||
|
||||
During BKL removal in 2.6.38, conversion of files from in-ICB format to normal
|
||||
format got broken. We call ->writepage with i_data_sem held but udf_get_block()
|
||||
also acquires i_data_sem thus creating A-A deadlock.
|
||||
|
||||
We fix the problem by dropping i_data_sem before calling ->writepage() which is
|
||||
safe since i_mutex still protects us against any changes in the file. Also fix
|
||||
pagelock - i_data_sem lock inversion in udf_expand_file_adinicb() by dropping
|
||||
i_data_sem before calling find_or_create_page().
|
||||
|
||||
Reported-by: Matthias Matiak <netzpython@mail-on.us>
|
||||
Tested-by: Matthias Matiak <netzpython@mail-on.us>
|
||||
Reviewed-by: Namjae Jeon <linkinjeon@gmail.com>
|
||||
Signed-off-by: Jan Kara <jack@suse.cz>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
fs/udf/file.c | 6 +++---
|
||||
fs/udf/inode.c | 21 ++++++++++++++++++---
|
||||
2 files changed, 21 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/fs/udf/file.c b/fs/udf/file.c
|
||||
index d8ffa7c..dca0c38 100644
|
||||
--- a/fs/udf/file.c
|
||||
+++ b/fs/udf/file.c
|
||||
@@ -125,7 +125,6 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
|
||||
err = udf_expand_file_adinicb(inode);
|
||||
if (err) {
|
||||
udf_debug("udf_expand_adinicb: err=%d\n", err);
|
||||
- up_write(&iinfo->i_data_sem);
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
@@ -133,9 +132,10 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
|
||||
iinfo->i_lenAlloc = pos + count;
|
||||
else
|
||||
iinfo->i_lenAlloc = inode->i_size;
|
||||
+ up_write(&iinfo->i_data_sem);
|
||||
}
|
||||
- }
|
||||
- up_write(&iinfo->i_data_sem);
|
||||
+ } else
|
||||
+ up_write(&iinfo->i_data_sem);
|
||||
|
||||
retval = generic_file_aio_write(iocb, iov, nr_segs, ppos);
|
||||
if (retval > 0)
|
||||
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
|
||||
index 4fd1d80..e2787d0 100644
|
||||
--- a/fs/udf/inode.c
|
||||
+++ b/fs/udf/inode.c
|
||||
@@ -151,6 +151,12 @@ const struct address_space_operations udf_aops = {
|
||||
.bmap = udf_bmap,
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * Expand file stored in ICB to a normal one-block-file
|
||||
+ *
|
||||
+ * This function requires i_data_sem for writing and releases it.
|
||||
+ * This function requires i_mutex held
|
||||
+ */
|
||||
int udf_expand_file_adinicb(struct inode *inode)
|
||||
{
|
||||
struct page *page;
|
||||
@@ -169,9 +175,15 @@ int udf_expand_file_adinicb(struct inode *inode)
|
||||
iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
|
||||
/* from now on we have normal address_space methods */
|
||||
inode->i_data.a_ops = &udf_aops;
|
||||
+ up_write(&iinfo->i_data_sem);
|
||||
mark_inode_dirty(inode);
|
||||
return 0;
|
||||
}
|
||||
+ /*
|
||||
+ * Release i_data_sem so that we can lock a page - page lock ranks
|
||||
+ * above i_data_sem. i_mutex still protects us against file changes.
|
||||
+ */
|
||||
+ up_write(&iinfo->i_data_sem);
|
||||
|
||||
page = find_or_create_page(inode->i_mapping, 0, GFP_NOFS);
|
||||
if (!page)
|
||||
@@ -187,6 +199,7 @@ int udf_expand_file_adinicb(struct inode *inode)
|
||||
SetPageUptodate(page);
|
||||
kunmap(page);
|
||||
}
|
||||
+ down_write(&iinfo->i_data_sem);
|
||||
memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr, 0x00,
|
||||
iinfo->i_lenAlloc);
|
||||
iinfo->i_lenAlloc = 0;
|
||||
@@ -196,17 +209,20 @@ int udf_expand_file_adinicb(struct inode *inode)
|
||||
iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
|
||||
/* from now on we have normal address_space methods */
|
||||
inode->i_data.a_ops = &udf_aops;
|
||||
+ up_write(&iinfo->i_data_sem);
|
||||
err = inode->i_data.a_ops->writepage(page, &udf_wbc);
|
||||
if (err) {
|
||||
/* Restore everything back so that we don't lose data... */
|
||||
lock_page(page);
|
||||
kaddr = kmap(page);
|
||||
+ down_write(&iinfo->i_data_sem);
|
||||
memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr, kaddr,
|
||||
inode->i_size);
|
||||
kunmap(page);
|
||||
unlock_page(page);
|
||||
iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
|
||||
inode->i_data.a_ops = &udf_adinicb_aops;
|
||||
+ up_write(&iinfo->i_data_sem);
|
||||
}
|
||||
page_cache_release(page);
|
||||
mark_inode_dirty(inode);
|
||||
@@ -1111,10 +1127,9 @@ int udf_setsize(struct inode *inode, loff_t newsize)
|
||||
if (bsize <
|
||||
(udf_file_entry_alloc_offset(inode) + newsize)) {
|
||||
err = udf_expand_file_adinicb(inode);
|
||||
- if (err) {
|
||||
- up_write(&iinfo->i_data_sem);
|
||||
+ if (err)
|
||||
return err;
|
||||
- }
|
||||
+ down_write(&iinfo->i_data_sem);
|
||||
} else
|
||||
iinfo->i_lenAlloc = newsize;
|
||||
}
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
From 2aabf017a2a76405dd9efbca80320965d8361302 Mon Sep 17 00:00:00 2001
|
||||
From: Julia Lawall <julia@diku.dk>
|
||||
Date: Fri, 23 Dec 2011 14:02:55 +0100
|
||||
Subject: [PATCH 33/49] drivers/usb/class/cdc-acm.c: clear dangling pointer
|
||||
|
||||
commit e7c8e8605d0bafc705ff27f9da98a1668427cc0f upstream.
|
||||
|
||||
On some failures, the country_code field of an acm structure is freed
|
||||
without freeing the acm structure itself. Elsewhere, operations including
|
||||
memcpy and kfree are performed on the country_code field. The patch sets
|
||||
the country_code field to NULL when it is freed, and likewise sets the
|
||||
country_code_size field to 0.
|
||||
|
||||
Signed-off-by: Julia Lawall <julia@diku.dk>
|
||||
Acked-by: Oliver Neukum <oneukum@suse.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/usb/class/cdc-acm.c | 4 ++++
|
||||
1 files changed, 4 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
|
||||
index a8078d0..ea5e487 100644
|
||||
--- a/drivers/usb/class/cdc-acm.c
|
||||
+++ b/drivers/usb/class/cdc-acm.c
|
||||
@@ -1183,6 +1183,8 @@ made_compressed_probe:
|
||||
i = device_create_file(&intf->dev, &dev_attr_wCountryCodes);
|
||||
if (i < 0) {
|
||||
kfree(acm->country_codes);
|
||||
+ acm->country_codes = NULL;
|
||||
+ acm->country_code_size = 0;
|
||||
goto skip_countries;
|
||||
}
|
||||
|
||||
@@ -1191,6 +1193,8 @@ made_compressed_probe:
|
||||
if (i < 0) {
|
||||
device_remove_file(&intf->dev, &dev_attr_wCountryCodes);
|
||||
kfree(acm->country_codes);
|
||||
+ acm->country_codes = NULL;
|
||||
+ acm->country_code_size = 0;
|
||||
goto skip_countries;
|
||||
}
|
||||
}
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
From 1d24cdb0797a26e1fb1d3545f6d4b992a5a23e96 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
Date: Mon, 5 Dec 2011 14:02:59 -0800
|
||||
Subject: [PATCH 34/49] USB: isight: fix kernel bug when loading firmware
|
||||
|
||||
commit 59bf5cf94f0fa3b08fb1258b52649077b7d0914d upstream.
|
||||
|
||||
We were sending data on the stack when uploading firmware, which causes
|
||||
some machines fits, and is not allowed. Fix this by using the buffer we
|
||||
already had around for this very purpose.
|
||||
|
||||
Reported-by: Wouter M. Koolen <wmkoolen@cwi.nl>
|
||||
Tested-by: Wouter M. Koolen <wmkoolen@cwi.nl>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/usb/misc/isight_firmware.c | 6 ++++--
|
||||
1 files changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/misc/isight_firmware.c b/drivers/usb/misc/isight_firmware.c
|
||||
index fe1d443..8f725f6 100644
|
||||
--- a/drivers/usb/misc/isight_firmware.c
|
||||
+++ b/drivers/usb/misc/isight_firmware.c
|
||||
@@ -55,8 +55,9 @@ static int isight_firmware_load(struct usb_interface *intf,
|
||||
|
||||
ptr = firmware->data;
|
||||
|
||||
+ buf[0] = 0x01;
|
||||
if (usb_control_msg
|
||||
- (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\1", 1,
|
||||
+ (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, buf, 1,
|
||||
300) != 1) {
|
||||
printk(KERN_ERR
|
||||
"Failed to initialise isight firmware loader\n");
|
||||
@@ -100,8 +101,9 @@ static int isight_firmware_load(struct usb_interface *intf,
|
||||
}
|
||||
}
|
||||
|
||||
+ buf[0] = 0x00;
|
||||
if (usb_control_msg
|
||||
- (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\0", 1,
|
||||
+ (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, buf, 1,
|
||||
300) != 1) {
|
||||
printk(KERN_ERR "isight firmware loading completion failed\n");
|
||||
ret = -ENODEV;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
From 713ad0e8402a7e377bb8b4254b9b522628c9afeb Mon Sep 17 00:00:00 2001
|
||||
From: Huajun Li <huajun.li.lee@gmail.com>
|
||||
Date: Wed, 4 Jan 2012 19:25:33 +0800
|
||||
Subject: [PATCH 35/49] usb: usb-storage doesn't support dynamic id currently,
|
||||
the patch disables the feature to fix an oops
|
||||
|
||||
commit 1a3a026ba1b6bbfe0b7f79ab38cf991d691e7c9a upstream.
|
||||
|
||||
Echo vendor and product number of a non usb-storage device to
|
||||
usb-storage driver's new_id, then plug in the device to host and you
|
||||
will find following oops msg, the root cause is usb_stor_probe1()
|
||||
refers invalid id entry if giving a dynamic id, so just disable the
|
||||
feature.
|
||||
|
||||
[ 3105.018012] general protection fault: 0000 [#1] SMP DEBUG_PAGEALLOC
|
||||
[ 3105.018062] CPU 0
|
||||
[ 3105.018075] Modules linked in: usb_storage usb_libusual bluetooth
|
||||
dm_crypt binfmt_misc snd_hda_codec_analog snd_hda_intel snd_hda_codec
|
||||
snd_hwdep hp_wmi ppdev sparse_keymap snd_pcm snd_seq_midi snd_rawmidi
|
||||
snd_seq_midi_event snd_seq snd_timer snd_seq_device psmouse snd
|
||||
serio_raw tpm_infineon soundcore i915 snd_page_alloc tpm_tis
|
||||
parport_pc tpm tpm_bios drm_kms_helper drm i2c_algo_bit video lp
|
||||
parport usbhid hid sg sr_mod sd_mod ehci_hcd uhci_hcd usbcore e1000e
|
||||
usb_common floppy
|
||||
[ 3105.018408]
|
||||
[ 3105.018419] Pid: 189, comm: khubd Tainted: G I 3.2.0-rc7+
|
||||
#29 Hewlett-Packard HP Compaq dc7800p Convertible Minitower/0AACh
|
||||
[ 3105.018481] RIP: 0010:[<ffffffffa045830d>] [<ffffffffa045830d>]
|
||||
usb_stor_probe1+0x2fd/0xc20 [usb_storage]
|
||||
[ 3105.018536] RSP: 0018:ffff880056a3d830 EFLAGS: 00010286
|
||||
[ 3105.018562] RAX: ffff880065f4e648 RBX: ffff88006bb28000 RCX: 0000000000000000
|
||||
[ 3105.018597] RDX: ffff88006f23c7b0 RSI: 0000000000000001 RDI: 0000000000000206
|
||||
[ 3105.018632] RBP: ffff880056a3d900 R08: 0000000000000000 R09: ffff880067365000
|
||||
[ 3105.018665] R10: 00000000000002ac R11: 0000000000000010 R12: ffff6000b41a7340
|
||||
[ 3105.018698] R13: ffff880065f4ef60 R14: ffff88006bb28b88 R15: ffff88006f23d270
|
||||
[ 3105.018733] FS: 0000000000000000(0000) GS:ffff88007a200000(0000)
|
||||
knlGS:0000000000000000
|
||||
[ 3105.018773] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
|
||||
[ 3105.018801] CR2: 00007fc99c8c4650 CR3: 0000000001e05000 CR4: 00000000000006f0
|
||||
[ 3105.018835] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
|
||||
[ 3105.018870] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
|
||||
[ 3105.018906] Process khubd (pid: 189, threadinfo ffff880056a3c000,
|
||||
task ffff88005677a400)
|
||||
[ 3105.018945] Stack:
|
||||
[ 3105.018959] 0000000000000000 0000000000000000 ffff880056a3d8d0
|
||||
0000000000000002
|
||||
[ 3105.019011] 0000000000000000 ffff880056a3d918 ffff880000000000
|
||||
0000000000000002
|
||||
[ 3105.019058] ffff880056a3d8d0 0000000000000012 ffff880056a3d8d0
|
||||
0000000000000006
|
||||
[ 3105.019105] Call Trace:
|
||||
[ 3105.019128] [<ffffffffa0458cd4>] storage_probe+0xa4/0xe0 [usb_storage]
|
||||
[ 3105.019173] [<ffffffffa0097822>] usb_probe_interface+0x172/0x330 [usbcore]
|
||||
[ 3105.019211] [<ffffffff815fda67>] driver_probe_device+0x257/0x3b0
|
||||
[ 3105.019243] [<ffffffff815fdd43>] __device_attach+0x73/0x90
|
||||
[ 3105.019272] [<ffffffff815fdcd0>] ? __driver_attach+0x110/0x110
|
||||
[ 3105.019303] [<ffffffff815fb93c>] bus_for_each_drv+0x9c/0xf0
|
||||
[ 3105.019334] [<ffffffff815fd6c7>] device_attach+0xf7/0x120
|
||||
[ 3105.019364] [<ffffffff815fc905>] bus_probe_device+0x45/0x80
|
||||
[ 3105.019396] [<ffffffff815f98a6>] device_add+0x876/0x990
|
||||
[ 3105.019434] [<ffffffffa0094e42>] usb_set_configuration+0x822/0x9e0 [usbcore]
|
||||
[ 3105.019479] [<ffffffffa00a3492>] generic_probe+0x62/0xf0 [usbcore]
|
||||
[ 3105.019518] [<ffffffffa0097a46>] usb_probe_device+0x66/0xb0 [usbcore]
|
||||
[ 3105.019555] [<ffffffff815fda67>] driver_probe_device+0x257/0x3b0
|
||||
[ 3105.019589] [<ffffffff815fdd43>] __device_attach+0x73/0x90
|
||||
[ 3105.019617] [<ffffffff815fdcd0>] ? __driver_attach+0x110/0x110
|
||||
[ 3105.019648] [<ffffffff815fb93c>] bus_for_each_drv+0x9c/0xf0
|
||||
[ 3105.019680] [<ffffffff815fd6c7>] device_attach+0xf7/0x120
|
||||
[ 3105.019709] [<ffffffff815fc905>] bus_probe_device+0x45/0x80
|
||||
[ 3105.021040] usb usb6: usb auto-resume
|
||||
[ 3105.021045] usb usb6: wakeup_rh
|
||||
[ 3105.024849] [<ffffffff815f98a6>] device_add+0x876/0x990
|
||||
[ 3105.025086] [<ffffffffa0088987>] usb_new_device+0x1e7/0x2b0 [usbcore]
|
||||
[ 3105.025086] [<ffffffffa008a4d7>] hub_thread+0xb27/0x1ec0 [usbcore]
|
||||
[ 3105.025086] [<ffffffff810d5200>] ? wake_up_bit+0x50/0x50
|
||||
[ 3105.025086] [<ffffffffa00899b0>] ? usb_remote_wakeup+0xa0/0xa0 [usbcore]
|
||||
[ 3105.025086] [<ffffffff810d49b8>] kthread+0xd8/0xf0
|
||||
[ 3105.025086] [<ffffffff81939884>] kernel_thread_helper+0x4/0x10
|
||||
[ 3105.025086] [<ffffffff8192a8c0>] ? _raw_spin_unlock_irq+0x50/0x80
|
||||
[ 3105.025086] [<ffffffff8192b1b4>] ? retint_restore_args+0x13/0x13
|
||||
[ 3105.025086] [<ffffffff810d48e0>] ? __init_kthread_worker+0x80/0x80
|
||||
[ 3105.025086] [<ffffffff81939880>] ? gs_change+0x13/0x13
|
||||
[ 3105.025086] Code: 00 48 83 05 cd ad 00 00 01 48 83 05 cd ad 00 00
|
||||
01 4c 8b ab 30 0c 00 00 48 8b 50 08 48 83 c0 30 48 89 45 a0 4c 89 a3
|
||||
40 0c 00 00 <41> 0f b6 44 24 10 48 89 55 a8 3c ff 0f 84 b8 04 00 00 48
|
||||
83 05
|
||||
[ 3105.025086] RIP [<ffffffffa045830d>] usb_stor_probe1+0x2fd/0xc20
|
||||
[usb_storage]
|
||||
[ 3105.025086] RSP <ffff880056a3d830>
|
||||
[ 3105.060037] hub 6-0:1.0: hub_resume
|
||||
[ 3105.062616] usb usb5: usb auto-resume
|
||||
[ 3105.064317] ehci_hcd 0000:00:1d.7: resume root hub
|
||||
[ 3105.094809] ---[ end trace a7919e7f17c0a727 ]---
|
||||
[ 3105.130069] hub 5-0:1.0: hub_resume
|
||||
[ 3105.132131] usb usb4: usb auto-resume
|
||||
[ 3105.132136] usb usb4: wakeup_rh
|
||||
[ 3105.180059] hub 4-0:1.0: hub_resume
|
||||
[ 3106.290052] usb usb6: suspend_rh (auto-stop)
|
||||
[ 3106.290077] usb usb4: suspend_rh (auto-stop)
|
||||
|
||||
Signed-off-by: Huajun Li <huajun.li.lee@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/usb/storage/usb.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
|
||||
index c325e69..9e069ef 100644
|
||||
--- a/drivers/usb/storage/usb.c
|
||||
+++ b/drivers/usb/storage/usb.c
|
||||
@@ -1073,6 +1073,7 @@ static struct usb_driver usb_storage_driver = {
|
||||
.id_table = usb_storage_usb_ids,
|
||||
.supports_autosuspend = 1,
|
||||
.soft_unbind = 1,
|
||||
+ .no_dynamic_id = 1,
|
||||
};
|
||||
|
||||
static int __init usb_stor_init(void)
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
From 17e7ea93a7ec7bb64e3bcd6b3cbee1fea5021587 Mon Sep 17 00:00:00 2001
|
||||
From: Tanmay Upadhyay <tanmay.upadhyay@einfochips.com>
|
||||
Date: Thu, 8 Dec 2011 10:03:49 +0530
|
||||
Subject: [PATCH 36/49] USB: pxa168: Fix compilation error
|
||||
|
||||
commit 35657c4d72925936c7219cc5caac118ca632acc2 upstream.
|
||||
|
||||
After commit c430131a02d677aa708f56342c1565edfdacb3c0 (Support
|
||||
controllers with big endian capability regs), HC_LENGTH takes
|
||||
two arguments. This patch fixes following compilation error:
|
||||
|
||||
In file included from drivers/usb/host/ehci-hcd.c:1323:
|
||||
drivers/usb/host/ehci-pxa168.c:302:54: error: macro "HC_LENGTH" requires 2 arguments, but only 1 given
|
||||
In file included from drivers/usb/host/ehci-hcd.c:1323:
|
||||
drivers/usb/host/ehci-pxa168.c: In function 'ehci_pxa168_drv_probe':
|
||||
drivers/usb/host/ehci-pxa168.c:302: error: 'HC_LENGTH' undeclared (first use in this function)
|
||||
drivers/usb/host/ehci-pxa168.c:302: error: (Each undeclared identifier is reported only once
|
||||
drivers/usb/host/ehci-pxa168.c:302: error: for each function it appears in.)
|
||||
|
||||
Signed-off-by: Tanmay Upadhyay <tanmay.upadhyay@einfochips.com>
|
||||
Acked-by: Alan Stern <stern@rowland.harvard.edu>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/usb/host/ehci-pxa168.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/host/ehci-pxa168.c b/drivers/usb/host/ehci-pxa168.c
|
||||
index ac0c16e..8d0e7a2 100644
|
||||
--- a/drivers/usb/host/ehci-pxa168.c
|
||||
+++ b/drivers/usb/host/ehci-pxa168.c
|
||||
@@ -299,7 +299,7 @@ static int __devinit ehci_pxa168_drv_probe(struct platform_device *pdev)
|
||||
ehci = hcd_to_ehci(hcd);
|
||||
ehci->caps = hcd->regs + 0x100;
|
||||
ehci->regs = hcd->regs + 0x100 +
|
||||
- HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
|
||||
+ HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
|
||||
ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
|
||||
hcd->has_tt = 1;
|
||||
ehci->sbrn = 0x20;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
From ae803972522d34f68270782827580ba0d762468c Mon Sep 17 00:00:00 2001
|
||||
From: Oliver Neukum <oliver@neukum.org>
|
||||
Date: Tue, 3 Jan 2012 09:58:54 +0100
|
||||
Subject: [PATCH 37/49] USB: add quirk for another camera
|
||||
|
||||
commit 35284b3d2f68a8a3703745e629999469f78386b5 upstream.
|
||||
|
||||
The Guillemot Webcam Hercules Dualpix Exchange camera
|
||||
has been reported with a second ID.
|
||||
|
||||
Signed-off-by: Oliver Neukum <oneukum@suse.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/usb/core/quirks.c | 5 ++++-
|
||||
1 files changed, 4 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
|
||||
index ecf12e1..4c65eb6 100644
|
||||
--- a/drivers/usb/core/quirks.c
|
||||
+++ b/drivers/usb/core/quirks.c
|
||||
@@ -117,9 +117,12 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
{ USB_DEVICE(0x06a3, 0x0006), .driver_info =
|
||||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||
|
||||
- /* Guillemot Webcam Hercules Dualpix Exchange*/
|
||||
+ /* Guillemot Webcam Hercules Dualpix Exchange (2nd ID) */
|
||||
{ USB_DEVICE(0x06f8, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
+ /* Guillemot Webcam Hercules Dualpix Exchange*/
|
||||
+ { USB_DEVICE(0x06f8, 0x3005), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
+
|
||||
/* M-Systems Flash Disk Pioneers */
|
||||
{ USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
From 4a6a3895c6ffe420a07f90df0f8ad5d7ac5a47a4 Mon Sep 17 00:00:00 2001
|
||||
From: Johan Hovold <jhovold@gmail.com>
|
||||
Date: Sun, 6 Nov 2011 19:06:21 +0100
|
||||
Subject: [PATCH 38/49] USB: omninet: fix write_room
|
||||
|
||||
commit 694c6301e515bad574af74b6552134c4d9dcb334 upstream.
|
||||
|
||||
Fix regression introduced by commit 507ca9bc047666 ([PATCH] USB: add
|
||||
ability for usb-serial drivers to determine if their write urb is
|
||||
currently being used.) which inverted the logic in write_room so that it
|
||||
returns zero when the write urb is actually free.
|
||||
|
||||
Signed-off-by: Johan Hovold <jhovold@gmail.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/usb/serial/omninet.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
|
||||
index 60f38d5..0a8c1e6 100644
|
||||
--- a/drivers/usb/serial/omninet.c
|
||||
+++ b/drivers/usb/serial/omninet.c
|
||||
@@ -315,7 +315,7 @@ static int omninet_write_room(struct tty_struct *tty)
|
||||
int room = 0; /* Default: no room */
|
||||
|
||||
/* FIXME: no consistent locking for write_urb_busy */
|
||||
- if (wport->write_urb_busy)
|
||||
+ if (!wport->write_urb_busy)
|
||||
room = wport->bulk_out_size - OMNINET_HEADERLEN;
|
||||
|
||||
dbg("%s - returns %d", __func__, room);
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
From bd6e892c7f49027eb7d6f5739406142db70fee7e Mon Sep 17 00:00:00 2001
|
||||
From: Janne Snabb <snabb@epipe.com>
|
||||
Date: Wed, 28 Dec 2011 19:36:00 +0000
|
||||
Subject: [PATCH 39/49] usb: option: add ZD Incorporated HSPA modem
|
||||
|
||||
commit 3c8c9316710b83e906e425024153bf0929887b59 upstream.
|
||||
|
||||
Add support for Chinese Noname HSPA USB modem which is apparently
|
||||
manufactured by a company called ZD Incorporated (based on texts in the
|
||||
Windows drivers).
|
||||
|
||||
This product is available at least from Dealextreme (SKU 80032) and
|
||||
possibly in India with name Olive V-MW250. It is based on Qualcomm
|
||||
MSM6280 chip.
|
||||
|
||||
I needed to also add "options usb-storage quirks=0685:7000:i" in modprobe
|
||||
configuration because udevd or the kernel keeps poking the embedded
|
||||
fake-cd-rom which fails and causes the device to reset. There might be
|
||||
a better way to accomplish the same. usb_modeswitch is not needed with
|
||||
this device.
|
||||
|
||||
Signed-off-by: Janne Snabb <snabb@epipe.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/usb/serial/option.c | 5 +++++
|
||||
1 files changed, 5 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
|
||||
index 6dd6453..c96b6b6 100644
|
||||
--- a/drivers/usb/serial/option.c
|
||||
+++ b/drivers/usb/serial/option.c
|
||||
@@ -476,6 +476,10 @@ static void option_instat_callback(struct urb *urb);
|
||||
#define VIETTEL_VENDOR_ID 0x2262
|
||||
#define VIETTEL_PRODUCT_VT1000 0x0002
|
||||
|
||||
+/* ZD Incorporated */
|
||||
+#define ZD_VENDOR_ID 0x0685
|
||||
+#define ZD_PRODUCT_7000 0x7000
|
||||
+
|
||||
/* some devices interfaces need special handling due to a number of reasons */
|
||||
enum option_blacklist_reason {
|
||||
OPTION_BLACKLIST_NONE = 0,
|
||||
@@ -1178,6 +1182,7 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) },
|
||||
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) },
|
||||
+ { USB_DEVICE_AND_INTERFACE_INFO(ZD_VENDOR_ID, ZD_PRODUCT_7000, 0xff, 0xff, 0xff) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, option_ids);
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
From a558d5668e8c66327a1a84f5db8381e94c2b0cd9 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Malte=20Schr=C3=B6der?= <maltesch@gmx.de>
|
||||
Date: Thu, 5 Jan 2012 20:34:40 +0100
|
||||
Subject: [PATCH 40/49] USB: Add USB-ID for Multiplex RC serial adapter to
|
||||
cp210x.c
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
commit 08e87d0d773dc9ca5faf4c3306e238ed0ea129b0 upstream.
|
||||
|
||||
Hi, below patch adds the USB-ID of the serial adapters sold by
|
||||
Multiplex RC (www.multiplex-rc.de).
|
||||
|
||||
Signed-off-by: Malte Schröder <maltesch@gmx.de>
|
||||
Cc: stable <stable@vger.kernel.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/usb/serial/cp210x.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
|
||||
index fd67cc5..a1a324b 100644
|
||||
--- a/drivers/usb/serial/cp210x.c
|
||||
+++ b/drivers/usb/serial/cp210x.c
|
||||
@@ -92,6 +92,7 @@ static const struct usb_device_id id_table[] = {
|
||||
{ USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */
|
||||
{ USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */
|
||||
{ USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */
|
||||
+ { USB_DEVICE(0x10C4, 0x81A9) }, /* Multiplex RC Interface */
|
||||
{ USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */
|
||||
{ USB_DEVICE(0x10C4, 0x81AD) }, /* INSYS USB Modem */
|
||||
{ USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
From 61ff4bd883cde399d333204fe9878e90b6f87329 Mon Sep 17 00:00:00 2001
|
||||
From: Clemens Ladisch <clemens@ladisch.de>
|
||||
Date: Sat, 3 Dec 2011 23:41:31 +0100
|
||||
Subject: [PATCH 41/49] usb: fix number of mapped SG DMA entries
|
||||
|
||||
commit bc677d5b64644c399cd3db6a905453e611f402ab upstream.
|
||||
|
||||
Add a new field num_mapped_sgs to struct urb so that we have a place to
|
||||
store the number of mapped entries and can also retain the original
|
||||
value of entries in num_sgs. Previously, usb_hcd_map_urb_for_dma()
|
||||
would overwrite this with the number of mapped entries, which would
|
||||
break dma_unmap_sg() because it requires the original number of entries.
|
||||
|
||||
This fixes warnings like the following when using USB storage devices:
|
||||
------------[ cut here ]------------
|
||||
WARNING: at lib/dma-debug.c:902 check_unmap+0x4e4/0x695()
|
||||
ehci_hcd 0000:00:12.2: DMA-API: device driver frees DMA sg list with different entry count [map count=4] [unmap count=1]
|
||||
Modules linked in: ohci_hcd ehci_hcd
|
||||
Pid: 0, comm: kworker/0:1 Not tainted 3.2.0-rc2+ #319
|
||||
Call Trace:
|
||||
<IRQ> [<ffffffff81036d3b>] warn_slowpath_common+0x80/0x98
|
||||
[<ffffffff81036de7>] warn_slowpath_fmt+0x41/0x43
|
||||
[<ffffffff811fa5ae>] check_unmap+0x4e4/0x695
|
||||
[<ffffffff8105e92c>] ? trace_hardirqs_off+0xd/0xf
|
||||
[<ffffffff8147208b>] ? _raw_spin_unlock_irqrestore+0x33/0x50
|
||||
[<ffffffff811fa84a>] debug_dma_unmap_sg+0xeb/0x117
|
||||
[<ffffffff8137b02f>] usb_hcd_unmap_urb_for_dma+0x71/0x188
|
||||
[<ffffffff8137b166>] unmap_urb_for_dma+0x20/0x22
|
||||
[<ffffffff8137b1c5>] usb_hcd_giveback_urb+0x5d/0xc0
|
||||
[<ffffffffa0000d02>] ehci_urb_done+0xf7/0x10c [ehci_hcd]
|
||||
[<ffffffffa0001140>] qh_completions+0x429/0x4bd [ehci_hcd]
|
||||
[<ffffffffa000340a>] ehci_work+0x95/0x9c0 [ehci_hcd]
|
||||
...
|
||||
---[ end trace f29ac88a5a48c580 ]---
|
||||
Mapped at:
|
||||
[<ffffffff811faac4>] debug_dma_map_sg+0x45/0x139
|
||||
[<ffffffff8137bc0b>] usb_hcd_map_urb_for_dma+0x22e/0x478
|
||||
[<ffffffff8137c494>] usb_hcd_submit_urb+0x63f/0x6fa
|
||||
[<ffffffff8137d01c>] usb_submit_urb+0x2c7/0x2de
|
||||
[<ffffffff8137dcd4>] usb_sg_wait+0x55/0x161
|
||||
|
||||
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/usb/core/hcd.c | 5 ++---
|
||||
drivers/usb/host/ehci-q.c | 2 +-
|
||||
drivers/usb/host/uhci-q.c | 2 +-
|
||||
drivers/usb/host/whci/qset.c | 4 ++--
|
||||
drivers/usb/host/xhci-ring.c | 4 ++--
|
||||
include/linux/usb.h | 1 +
|
||||
6 files changed, 9 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
|
||||
index 13222d3..179e364 100644
|
||||
--- a/drivers/usb/core/hcd.c
|
||||
+++ b/drivers/usb/core/hcd.c
|
||||
@@ -1412,11 +1412,10 @@ int usb_hcd_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
|
||||
ret = -EAGAIN;
|
||||
else
|
||||
urb->transfer_flags |= URB_DMA_MAP_SG;
|
||||
- if (n != urb->num_sgs) {
|
||||
- urb->num_sgs = n;
|
||||
+ urb->num_mapped_sgs = n;
|
||||
+ if (n != urb->num_sgs)
|
||||
urb->transfer_flags |=
|
||||
URB_DMA_SG_COMBINED;
|
||||
- }
|
||||
} else if (urb->sg) {
|
||||
struct scatterlist *sg = urb->sg;
|
||||
urb->transfer_dma = dma_map_page(
|
||||
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
|
||||
index 4e4066c..fef1db3 100644
|
||||
--- a/drivers/usb/host/ehci-q.c
|
||||
+++ b/drivers/usb/host/ehci-q.c
|
||||
@@ -647,7 +647,7 @@ qh_urb_transaction (
|
||||
/*
|
||||
* data transfer stage: buffer setup
|
||||
*/
|
||||
- i = urb->num_sgs;
|
||||
+ i = urb->num_mapped_sgs;
|
||||
if (len > 0 && i > 0) {
|
||||
sg = urb->sg;
|
||||
buf = sg_dma_address(sg);
|
||||
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
|
||||
index f6ca80e..d2c6f5a 100644
|
||||
--- a/drivers/usb/host/uhci-q.c
|
||||
+++ b/drivers/usb/host/uhci-q.c
|
||||
@@ -943,7 +943,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
|
||||
if (usb_pipein(urb->pipe))
|
||||
status |= TD_CTRL_SPD;
|
||||
|
||||
- i = urb->num_sgs;
|
||||
+ i = urb->num_mapped_sgs;
|
||||
if (len > 0 && i > 0) {
|
||||
sg = urb->sg;
|
||||
data = sg_dma_address(sg);
|
||||
diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c
|
||||
index a403b53..76083ae 100644
|
||||
--- a/drivers/usb/host/whci/qset.c
|
||||
+++ b/drivers/usb/host/whci/qset.c
|
||||
@@ -443,7 +443,7 @@ static int qset_add_urb_sg(struct whc *whc, struct whc_qset *qset, struct urb *u
|
||||
|
||||
remaining = urb->transfer_buffer_length;
|
||||
|
||||
- for_each_sg(urb->sg, sg, urb->num_sgs, i) {
|
||||
+ for_each_sg(urb->sg, sg, urb->num_mapped_sgs, i) {
|
||||
dma_addr_t dma_addr;
|
||||
size_t dma_remaining;
|
||||
dma_addr_t sp, ep;
|
||||
@@ -561,7 +561,7 @@ static int qset_add_urb_sg_linearize(struct whc *whc, struct whc_qset *qset,
|
||||
|
||||
remaining = urb->transfer_buffer_length;
|
||||
|
||||
- for_each_sg(urb->sg, sg, urb->num_sgs, i) {
|
||||
+ for_each_sg(urb->sg, sg, urb->num_mapped_sgs, i) {
|
||||
size_t len;
|
||||
size_t sg_remaining;
|
||||
void *orig;
|
||||
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
|
||||
index 9f1d4b1..d28c586 100644
|
||||
--- a/drivers/usb/host/xhci-ring.c
|
||||
+++ b/drivers/usb/host/xhci-ring.c
|
||||
@@ -2561,7 +2561,7 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb)
|
||||
struct scatterlist *sg;
|
||||
|
||||
sg = NULL;
|
||||
- num_sgs = urb->num_sgs;
|
||||
+ num_sgs = urb->num_mapped_sgs;
|
||||
temp = urb->transfer_buffer_length;
|
||||
|
||||
xhci_dbg(xhci, "count sg list trbs: \n");
|
||||
@@ -2745,7 +2745,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
||||
return -EINVAL;
|
||||
|
||||
num_trbs = count_sg_trbs_needed(xhci, urb);
|
||||
- num_sgs = urb->num_sgs;
|
||||
+ num_sgs = urb->num_mapped_sgs;
|
||||
total_packet_count = roundup(urb->transfer_buffer_length,
|
||||
usb_endpoint_maxp(&urb->ep->desc));
|
||||
|
||||
diff --git a/include/linux/usb.h b/include/linux/usb.h
|
||||
index 1cea207..7626e5a 100644
|
||||
--- a/include/linux/usb.h
|
||||
+++ b/include/linux/usb.h
|
||||
@@ -1222,6 +1222,7 @@ struct urb {
|
||||
void *transfer_buffer; /* (in) associated data buffer */
|
||||
dma_addr_t transfer_dma; /* (in) dma addr for transfer_buffer */
|
||||
struct scatterlist *sg; /* (in) scatter gather buffer list */
|
||||
+ int num_mapped_sgs; /* (internal) mapped sg entries */
|
||||
int num_sgs; /* (in) number of entries in the sg list */
|
||||
u32 transfer_buffer_length; /* (in) data buffer length */
|
||||
u32 actual_length; /* (return) actual transfer length */
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
From df0f4624e1225d9b7fb4d8934565418c81b42c04 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
Date: Wed, 4 Jan 2012 23:29:18 +0100
|
||||
Subject: [PATCH 42/49] xhci: Properly handle COMP_2ND_BW_ERR
|
||||
|
||||
commit 71d85724bdd947a3b42a88d08af79f290a1a767b upstream.
|
||||
|
||||
I encountered a result of COMP_2ND_BW_ERR while improving how the pwc
|
||||
webcam driver handles not having the full usb1 bandwidth available to
|
||||
itself.
|
||||
|
||||
I created the following test setup, a NEC xhci controller with a
|
||||
single TT USB 2 hub plugged into it, with a usb keyboard and a pwc webcam
|
||||
plugged into the usb2 hub. This caused the following to show up in dmesg
|
||||
when trying to stream from the pwc camera at its highest alt setting:
|
||||
|
||||
xhci_hcd 0000:01:00.0: ERROR: unexpected command completion code 0x23.
|
||||
usb 6-2.1: Not enough bandwidth for altsetting 9
|
||||
|
||||
And usb_set_interface returned -EINVAL, which caused my pwc code to not
|
||||
do the right thing as it expected -ENOSPC.
|
||||
|
||||
This patch makes the xhci driver properly handle COMP_2ND_BW_ERR and makes
|
||||
usb_set_interface return -ENOSPC as expected.
|
||||
|
||||
This should be backported to stable kernels as old as 2.6.32.
|
||||
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/usb/host/xhci.c | 1 +
|
||||
drivers/usb/host/xhci.h | 1 -
|
||||
2 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
|
||||
index a1afb7c..36f9dd8 100644
|
||||
--- a/drivers/usb/host/xhci.c
|
||||
+++ b/drivers/usb/host/xhci.c
|
||||
@@ -1620,6 +1620,7 @@ static int xhci_configure_endpoint_result(struct xhci_hcd *xhci,
|
||||
/* FIXME: can we allocate more resources for the HC? */
|
||||
break;
|
||||
case COMP_BW_ERR:
|
||||
+ case COMP_2ND_BW_ERR:
|
||||
dev_warn(&udev->dev, "Not enough bandwidth "
|
||||
"for new device state.\n");
|
||||
ret = -ENOSPC;
|
||||
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
|
||||
index 3c8fbd2..09eda3a 100644
|
||||
--- a/drivers/usb/host/xhci.h
|
||||
+++ b/drivers/usb/host/xhci.h
|
||||
@@ -1033,7 +1033,6 @@ struct xhci_transfer_event {
|
||||
/* Invalid Stream ID Error */
|
||||
#define COMP_STRID_ERR 34
|
||||
/* Secondary Bandwidth Error - may be returned by a Configure Endpoint cmd */
|
||||
-/* FIXME - check for this */
|
||||
#define COMP_2ND_BW_ERR 35
|
||||
/* Split Transaction Error */
|
||||
#define COMP_SPLIT_ERR 36
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
From db46f35cb2853ffa42157c7222335cae15eda7e0 Mon Sep 17 00:00:00 2001
|
||||
From: Felipe Balbi <balbi@ti.com>
|
||||
Date: Mon, 2 Jan 2012 13:35:41 +0200
|
||||
Subject: [PATCH 43/49] usb: ch9: fix up MaxStreams helper
|
||||
|
||||
commit 18b7ede5f7ee2092aedcb578d3ac30bd5d4fc23c upstream.
|
||||
|
||||
[ removed the dwc3 portion of the patch as it didn't apply to
|
||||
older kernels - gregkh]
|
||||
|
||||
According to USB 3.0 Specification Table 9-22, if
|
||||
bmAttributes [4:0] are set to zero, it means "no
|
||||
streams supported", but the way this helper was
|
||||
defined on Linux, we will *always* have one stream
|
||||
which might cause several problems.
|
||||
|
||||
For example on DWC3, we would tell the controller
|
||||
endpoint has streams enabled and yet start transfers
|
||||
with Stream ID set to 0, which would goof up the host
|
||||
side.
|
||||
|
||||
While doing that, convert the macro to an inline
|
||||
function due to the different checks we now need.
|
||||
|
||||
Signed-off-by: Felipe Balbi <balbi@ti.com>
|
||||
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/usb/host/xhci.c | 3 +--
|
||||
include/linux/usb/ch9.h | 20 +++++++++++++++++++-
|
||||
2 files changed, 20 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
|
||||
index 36f9dd8..b33f059 100644
|
||||
--- a/drivers/usb/host/xhci.c
|
||||
+++ b/drivers/usb/host/xhci.c
|
||||
@@ -2797,8 +2797,7 @@ static int xhci_calculate_streams_and_bitmask(struct xhci_hcd *xhci,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- max_streams = USB_SS_MAX_STREAMS(
|
||||
- eps[i]->ss_ep_comp.bmAttributes);
|
||||
+ max_streams = usb_ss_max_streams(&eps[i]->ss_ep_comp);
|
||||
if (max_streams < (*num_streams - 1)) {
|
||||
xhci_dbg(xhci, "Ep 0x%x only supports %u stream IDs.\n",
|
||||
eps[i]->desc.bEndpointAddress,
|
||||
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
|
||||
index d5da6c6..61b2905 100644
|
||||
--- a/include/linux/usb/ch9.h
|
||||
+++ b/include/linux/usb/ch9.h
|
||||
@@ -605,8 +605,26 @@ struct usb_ss_ep_comp_descriptor {
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define USB_DT_SS_EP_COMP_SIZE 6
|
||||
+
|
||||
/* Bits 4:0 of bmAttributes if this is a bulk endpoint */
|
||||
-#define USB_SS_MAX_STREAMS(p) (1 << ((p) & 0x1f))
|
||||
+static inline int
|
||||
+usb_ss_max_streams(const struct usb_ss_ep_comp_descriptor *comp)
|
||||
+{
|
||||
+ int max_streams;
|
||||
+
|
||||
+ if (!comp)
|
||||
+ return 0;
|
||||
+
|
||||
+ max_streams = comp->bmAttributes & 0x1f;
|
||||
+
|
||||
+ if (!max_streams)
|
||||
+ return 0;
|
||||
+
|
||||
+ max_streams = 1 << max_streams;
|
||||
+
|
||||
+ return max_streams;
|
||||
+}
|
||||
+
|
||||
/* Bits 1:0 of bmAttributes if this is an isoc endpoint */
|
||||
#define USB_SS_MULT(p) (1 + ((p) & 0x3))
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
From 53876956cbd176ad0da89ca8e066202f6c143ea8 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Mon, 9 Jan 2012 14:06:46 -0800
|
||||
Subject: [PATCH 44/49] igmp: Avoid zero delay when receiving odd mixture of
|
||||
IGMP queries
|
||||
|
||||
commit a8c1f65c79cbbb2f7da782d4c9d15639a9b94b27 upstream.
|
||||
|
||||
Commit 5b7c84066733c5dfb0e4016d939757b38de189e4 ('ipv4: correct IGMP
|
||||
behavior on v3 query during v2-compatibility mode') added yet another
|
||||
case for query parsing, which can result in max_delay = 0. Substitute
|
||||
a value of 1, as in the usual v3 case.
|
||||
|
||||
Reported-by: Simon McVittie <smcv@debian.org>
|
||||
References: http://bugs.debian.org/654876
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
net/ipv4/igmp.c | 2 ++
|
||||
1 files changed, 2 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
|
||||
index b2ca095..c3cc64c 100644
|
||||
--- a/net/ipv4/igmp.c
|
||||
+++ b/net/ipv4/igmp.c
|
||||
@@ -875,6 +875,8 @@ static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb,
|
||||
* to be intended in a v3 query.
|
||||
*/
|
||||
max_delay = IGMPV3_MRC(ih3->code)*(HZ/IGMP_TIMER_SCALE);
|
||||
+ if (!max_delay)
|
||||
+ max_delay = 1; /* can't mod w/ 0 */
|
||||
} else { /* v3 */
|
||||
if (!pskb_may_pull(skb, sizeof(struct igmpv3_query)))
|
||||
return;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
From eaa03e7a01f7dd67773c27e82d446a44440843a6 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien Jacobs <aurel@gnuage.org>
|
||||
Date: Sat, 7 Jan 2012 12:15:16 -0800
|
||||
Subject: [PATCH 45/49] asix: fix infinite loop in rx_fixup()
|
||||
|
||||
commit 6c15d74defd38e7e7f8805392578b7a1d508097e upstream.
|
||||
|
||||
At this point if skb->len happens to be 2, the subsequant skb_pull(skb, 4)
|
||||
call won't work and the skb->len won't be decreased and won't ever reach 0,
|
||||
resulting in an infinite loop.
|
||||
|
||||
With an ASIX 88772 under heavy load, without this patch, rx_fixup() reaches
|
||||
an infinite loop in less than a minute. With this patch applied,
|
||||
no infinite loop even after hours of heavy load.
|
||||
|
||||
Signed-off-by: Aurelien Jacobs <aurel@gnuage.org>
|
||||
Cc: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/usb/asix.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
|
||||
index e95f0e6..dd2625a 100644
|
||||
--- a/drivers/net/usb/asix.c
|
||||
+++ b/drivers/net/usb/asix.c
|
||||
@@ -376,7 +376,7 @@ static int asix_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
|
||||
|
||||
skb_pull(skb, (size + 1) & 0xfffe);
|
||||
|
||||
- if (skb->len == 0)
|
||||
+ if (skb->len < sizeof(header))
|
||||
break;
|
||||
|
||||
head = (u8 *) skb->data;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
From b40864c73fef3aefced0863fc2b3c3a7716d9f09 Mon Sep 17 00:00:00 2001
|
||||
From: stephen hemminger <shemminger@vyatta.com>
|
||||
Date: Sat, 31 Dec 2011 13:26:46 +0000
|
||||
Subject: [PATCH 46/49] bonding: fix error handling if slave is busy (v2)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
commit f7d9821a6a9c83450ac35e76d3709e32fd38b76f upstream.
|
||||
|
||||
If slave device already has a receive handler registered, then the
|
||||
error unwind of bonding device enslave function is broken.
|
||||
|
||||
The following will leave a pointer to freed memory in the slave
|
||||
device list, causing a later kernel panic.
|
||||
# modprobe dummy
|
||||
# ip li add dummy0-1 link dummy0 type macvlan
|
||||
# modprobe bonding
|
||||
# echo +dummy0 >/sys/class/net/bond0/bonding/slaves
|
||||
|
||||
The fix is to detach the slave (which removes it from the list)
|
||||
in the unwind path.
|
||||
|
||||
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
|
||||
Reviewed-by: Nicolas de Pesloüan <nicolas.2p.debian@free.fr>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/net/bonding/bond_main.c | 9 +++++++--
|
||||
1 files changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
|
||||
index 7f87568..e58aa2b 100644
|
||||
--- a/drivers/net/bonding/bond_main.c
|
||||
+++ b/drivers/net/bonding/bond_main.c
|
||||
@@ -1822,7 +1822,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
||||
"but new slave device does not support netpoll.\n",
|
||||
bond_dev->name);
|
||||
res = -EBUSY;
|
||||
- goto err_close;
|
||||
+ goto err_detach;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1831,7 +1831,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
||||
|
||||
res = bond_create_slave_symlinks(bond_dev, slave_dev);
|
||||
if (res)
|
||||
- goto err_close;
|
||||
+ goto err_detach;
|
||||
|
||||
res = netdev_rx_handler_register(slave_dev, bond_handle_frame,
|
||||
new_slave);
|
||||
@@ -1852,6 +1852,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
||||
err_dest_symlinks:
|
||||
bond_destroy_slave_symlinks(bond_dev, slave_dev);
|
||||
|
||||
+err_detach:
|
||||
+ write_lock_bh(&bond->lock);
|
||||
+ bond_detach_slave(bond, new_slave);
|
||||
+ write_unlock_bh(&bond->lock);
|
||||
+
|
||||
err_close:
|
||||
dev_close(slave_dev);
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
From 9d3898fe46309ee5688697d1a65975208dc49639 Mon Sep 17 00:00:00 2001
|
||||
From: Thilo-Alexander Ginkel <thilo@ginkel.com>
|
||||
Date: Sat, 17 Dec 2011 10:55:10 +0100
|
||||
Subject: [PATCH 47/49] usb: cdc-acm: Fix acm_tty_hangup() vs. acm_tty_close()
|
||||
race
|
||||
|
||||
[Not upstream as it was fixed differently for 3.3 with a much more
|
||||
"intrusive" rework of the driver - gregkh]
|
||||
|
||||
There is a race condition involving acm_tty_hangup() and acm_tty_close()
|
||||
where hangup() would attempt to access tty->driver_data without proper
|
||||
locking and NULL checking after close() has potentially already set it
|
||||
to NULL. One possibility to (sporadically) trigger this behavior is to
|
||||
perform a suspend/resume cycle with a running WWAN data connection.
|
||||
|
||||
This patch addresses the issue by introducing a NULL check for
|
||||
tty->driver_data in acm_tty_hangup() protected by open_mutex and exiting
|
||||
gracefully when hangup() is invoked on a device that has already been
|
||||
closed.
|
||||
|
||||
Signed-off-by: Thilo-Alexander Ginkel <thilo@ginkel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/usb/class/cdc-acm.c | 12 ++++++++++--
|
||||
1 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
|
||||
index ea5e487..e61d9c4 100644
|
||||
--- a/drivers/usb/class/cdc-acm.c
|
||||
+++ b/drivers/usb/class/cdc-acm.c
|
||||
@@ -554,10 +554,18 @@ static void acm_port_down(struct acm *acm)
|
||||
|
||||
static void acm_tty_hangup(struct tty_struct *tty)
|
||||
{
|
||||
- struct acm *acm = tty->driver_data;
|
||||
- tty_port_hangup(&acm->port);
|
||||
+ struct acm *acm;
|
||||
+
|
||||
mutex_lock(&open_mutex);
|
||||
+ acm = tty->driver_data;
|
||||
+
|
||||
+ if (!acm)
|
||||
+ goto out;
|
||||
+
|
||||
+ tty_port_hangup(&acm->port);
|
||||
acm_port_down(acm);
|
||||
+
|
||||
+out:
|
||||
mutex_unlock(&open_mutex);
|
||||
}
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
From 5af63c5af9a335ff2af8d6b84d512e92ac522995 Mon Sep 17 00:00:00 2001
|
||||
From: Xi Wang <xi.wang@gmail.com>
|
||||
Date: Mon, 12 Dec 2011 21:55:52 +0000
|
||||
Subject: [PATCH 48/49] xfs: fix acl count validation in xfs_acl_from_disk()
|
||||
|
||||
commit 093019cf1b18dd31b2c3b77acce4e000e2cbc9ce upstream.
|
||||
|
||||
Commit fa8b18ed didn't prevent the integer overflow and possible
|
||||
memory corruption. "count" can go negative and bypass the check.
|
||||
|
||||
Signed-off-by: Xi Wang <xi.wang@gmail.com>
|
||||
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
||||
Signed-off-by: Ben Myers <bpm@sgi.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
fs/xfs/xfs_acl.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
|
||||
index 76e4266..ac702a6 100644
|
||||
--- a/fs/xfs/xfs_acl.c
|
||||
+++ b/fs/xfs/xfs_acl.c
|
||||
@@ -39,7 +39,7 @@ xfs_acl_from_disk(struct xfs_acl *aclp)
|
||||
struct posix_acl_entry *acl_e;
|
||||
struct posix_acl *acl;
|
||||
struct xfs_acl_entry *ace;
|
||||
- int count, i;
|
||||
+ unsigned int count, i;
|
||||
|
||||
count = be32_to_cpu(aclp->acl_cnt);
|
||||
if (count > XFS_ACL_MAX_ENTRIES)
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
From 78d772bb92fa633fc41d234887b050dce88542bc Mon Sep 17 00:00:00 2001
|
||||
From: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
Date: Thu, 12 Jan 2012 11:42:45 -0800
|
||||
Subject: [PATCH 49/49] Linux 3.2.1
|
||||
|
||||
---
|
||||
Makefile | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/Makefile b/Makefile
|
||||
index adddd11..c5edffa 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,6 +1,6 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 2
|
||||
-SUBLEVEL = 0
|
||||
+SUBLEVEL = 1
|
||||
EXTRAVERSION =
|
||||
NAME = Saber-toothed Squirrel
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
From 9589d3910b50c6e66f1a050e365c22271936b6b0 Mon Sep 17 00:00:00 2001
|
||||
From: Roman Tereshonkov <roman.tereshonkov@nokia.com>
|
||||
Date: Tue, 29 Nov 2011 12:49:18 +0200
|
||||
Subject: [PATCH 001/130] mtdoops: fix the oops_page_used array size
|
||||
|
||||
commit 556f063580db2953a7e53cd46b47724246320f60 upstream.
|
||||
|
||||
The array of unsigned long pointed by oops_page_used is allocated
|
||||
by vmalloc which requires the size to be in bytes.
|
||||
|
||||
BITS_PER_LONG is equal to 32.
|
||||
If we want to allocate memory for 32 pages with one bit per page then
|
||||
32 / BITS_PER_LONG is equal to 1 byte that is 8 bits.
|
||||
To fix it we need to multiply the result by sizeof(unsigned long) equal to 4.
|
||||
|
||||
Signed-off-by: Roman Tereshonkov <roman.tereshonkov@nokia.com>
|
||||
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@linux.intel.com>
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/mtd/mtdoops.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
|
||||
index 1e2fa62..0782b31 100644
|
||||
--- a/drivers/mtd/mtdoops.c
|
||||
+++ b/drivers/mtd/mtdoops.c
|
||||
@@ -369,7 +369,7 @@ static void mtdoops_notify_add(struct mtd_info *mtd)
|
||||
|
||||
/* oops_page_used is a bit field */
|
||||
cxt->oops_page_used = vmalloc(DIV_ROUND_UP(mtdoops_pages,
|
||||
- BITS_PER_LONG));
|
||||
+ BITS_PER_LONG) * sizeof(unsigned long));
|
||||
if (!cxt->oops_page_used) {
|
||||
printk(KERN_ERR "mtdoops: could not allocate page array\n");
|
||||
return;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
From e8f072aad40b7d45c605e27f1337b5eb7b6fbc11 Mon Sep 17 00:00:00 2001
|
||||
From: Roman Tereshonkov <roman.tereshonkov@nokia.com>
|
||||
Date: Fri, 2 Dec 2011 15:07:17 +0200
|
||||
Subject: [PATCH 002/130] mtd: mtdoops: skip reading initially bad blocks
|
||||
|
||||
commit 3538c56329936c78f7d356889908790006d0124c upstream.
|
||||
|
||||
Use block_isbad to check and skip the bad blocks reading.
|
||||
This will allow to get rid of the read errors if bad blocks
|
||||
are present initially.
|
||||
|
||||
Signed-off-by: Roman Tereshonkov <roman.tereshonkov@nokia.com>
|
||||
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/mtd/mtdoops.c | 3 +++
|
||||
1 files changed, 3 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
|
||||
index 0782b31..f3cdce9 100644
|
||||
--- a/drivers/mtd/mtdoops.c
|
||||
+++ b/drivers/mtd/mtdoops.c
|
||||
@@ -253,6 +253,9 @@ static void find_next_position(struct mtdoops_context *cxt)
|
||||
size_t retlen;
|
||||
|
||||
for (page = 0; page < cxt->oops_pages; page++) {
|
||||
+ if (mtd->block_isbad &&
|
||||
+ mtd->block_isbad(mtd, page * record_size))
|
||||
+ continue;
|
||||
/* Assume the page is used */
|
||||
mark_page_used(cxt, page);
|
||||
ret = mtd->read(mtd, page * record_size, MTDOOPS_HEADER_SIZE,
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
From 7e1c31ad0d3116ac301e5d6ef6df036eec548229 Mon Sep 17 00:00:00 2001
|
||||
From: Brian Norris <computersforpeace@gmail.com>
|
||||
Date: Mon, 7 Nov 2011 15:51:05 -0800
|
||||
Subject: [PATCH 003/130] mtd: mtd_blkdevs: don't increase 'open' count on
|
||||
error path
|
||||
|
||||
commit 342ff28f5a2e5aa3236617bd2bddf6c749677ef2 upstream.
|
||||
|
||||
Some error paths in mtd_blkdevs were fixed in the following commit:
|
||||
|
||||
commit 94735ec4044a6d318b83ad3c5794e931ed168d10
|
||||
mtd: mtd_blkdevs: fix error path in blktrans_open
|
||||
|
||||
But on these error paths, the block device's `dev->open' count is
|
||||
already incremented before we check for errors. This meant that, while
|
||||
the error path was handled correctly on the first time through
|
||||
blktrans_open(), the device is erroneously considered already open on
|
||||
the second time through.
|
||||
|
||||
This problem can be seen, for instance, when a UBI volume is
|
||||
simultaneously mounted as a UBIFS partition and read through its
|
||||
corresponding gluebi mtdblockX device. This results in blktrans_open()
|
||||
passing its error checks (with `dev->open > 0') without actually having
|
||||
a handle on the device. Here's a summarized log of the actions and
|
||||
results with nandsim:
|
||||
|
||||
# modprobe nandsim
|
||||
# modprobe mtdblock
|
||||
# modprobe gluebi
|
||||
# modprobe ubifs
|
||||
# ubiattach /dev/ubi_ctrl -m 0
|
||||
...
|
||||
# ubimkvol /dev/ubi0 -N test -s 16MiB
|
||||
...
|
||||
# mount -t ubifs ubi0:test /mnt
|
||||
# ls /dev/mtdblock*
|
||||
/dev/mtdblock0 /dev/mtdblock1
|
||||
# cat /dev/mtdblock1 > /dev/null
|
||||
cat: can't open '/dev/mtdblock4': Device or resource busy
|
||||
# cat /dev/mtdblock1 > /dev/null
|
||||
|
||||
CPU 0 Unable to handle kernel paging request at virtual address
|
||||
fffffff0, epc == 8031536c, ra == 8031f280
|
||||
Oops[#1]:
|
||||
...
|
||||
Call Trace:
|
||||
[<8031536c>] ubi_leb_read+0x14/0x164
|
||||
[<8031f280>] gluebi_read+0xf0/0x148
|
||||
[<802edba8>] mtdblock_readsect+0x64/0x198
|
||||
[<802ecfe4>] mtd_blktrans_thread+0x330/0x3f4
|
||||
[<8005be98>] kthread+0x88/0x90
|
||||
[<8000bc04>] kernel_thread_helper+0x10/0x18
|
||||
|
||||
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
|
||||
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@linux.intel.com>
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/mtd/mtd_blkdevs.c | 3 ++-
|
||||
1 files changed, 2 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
|
||||
index ed8b5e7..424ca5f 100644
|
||||
--- a/drivers/mtd/mtd_blkdevs.c
|
||||
+++ b/drivers/mtd/mtd_blkdevs.c
|
||||
@@ -215,7 +215,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)
|
||||
|
||||
mutex_lock(&dev->lock);
|
||||
|
||||
- if (dev->open++)
|
||||
+ if (dev->open)
|
||||
goto unlock;
|
||||
|
||||
kref_get(&dev->ref);
|
||||
@@ -235,6 +235,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)
|
||||
goto error_release;
|
||||
|
||||
unlock:
|
||||
+ dev->open++;
|
||||
mutex_unlock(&dev->lock);
|
||||
blktrans_dev_put(dev);
|
||||
return ret;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
From 24935db264c015f91046c597ead8f42a3de24858 Mon Sep 17 00:00:00 2001
|
||||
From: Wolfram Sang <w.sang@pengutronix.de>
|
||||
Date: Tue, 29 Nov 2011 15:34:08 +0100
|
||||
Subject: [PATCH 004/130] mtd: tests: stresstest: bail out if device has not
|
||||
enough eraseblocks
|
||||
|
||||
commit 2f4478ccff7df845dc9c0f8996a96373122c4417 upstream.
|
||||
|
||||
stresstest needs at least two eraseblocks. Bail out gracefully if that
|
||||
condition is not met. Fixes the following 'division by zero' OOPS:
|
||||
|
||||
[ 619.100000] mtd_stresstest: MTD device size 131072, eraseblock size 131072, page size 2048, count of eraseblocks 1, pages per eraseblock 64, OOB size 64
|
||||
[ 619.120000] mtd_stresstest: scanning for bad eraseblocks
|
||||
[ 619.120000] mtd_stresstest: scanned 1 eraseblocks, 0 are bad
|
||||
[ 619.130000] mtd_stresstest: doing operations
|
||||
[ 619.130000] mtd_stresstest: 0 operations done
|
||||
[ 619.140000] Division by zero in kernel.
|
||||
...
|
||||
|
||||
caused by
|
||||
|
||||
/* Read or write up 2 eraseblocks at a time - hence 'ebcnt - 1' */
|
||||
eb %= (ebcnt - 1);
|
||||
|
||||
Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
|
||||
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/mtd/tests/mtd_stresstest.c | 7 +++++++
|
||||
1 files changed, 7 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/tests/mtd_stresstest.c b/drivers/mtd/tests/mtd_stresstest.c
|
||||
index 52ffd91..811642f 100644
|
||||
--- a/drivers/mtd/tests/mtd_stresstest.c
|
||||
+++ b/drivers/mtd/tests/mtd_stresstest.c
|
||||
@@ -284,6 +284,12 @@ static int __init mtd_stresstest_init(void)
|
||||
(unsigned long long)mtd->size, mtd->erasesize,
|
||||
pgsize, ebcnt, pgcnt, mtd->oobsize);
|
||||
|
||||
+ if (ebcnt < 2) {
|
||||
+ printk(PRINT_PREF "error: need at least 2 eraseblocks\n");
|
||||
+ err = -ENOSPC;
|
||||
+ goto out_put_mtd;
|
||||
+ }
|
||||
+
|
||||
/* Read or write up 2 eraseblocks at a time */
|
||||
bufsize = mtd->erasesize * 2;
|
||||
|
||||
@@ -322,6 +328,7 @@ out:
|
||||
kfree(bbt);
|
||||
vfree(writebuf);
|
||||
vfree(readbuf);
|
||||
+out_put_mtd:
|
||||
put_mtd_device(mtd);
|
||||
if (err)
|
||||
printk(PRINT_PREF "error %d occurred\n", err);
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
From 0ff595b93bc982c60777d727c282cf76050802bf Mon Sep 17 00:00:00 2001
|
||||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Tue, 10 Jan 2012 15:11:02 -0800
|
||||
Subject: [PATCH 005/130] drivers/rtc/interface.c: fix alarm rollover when day
|
||||
or month is out-of-range
|
||||
|
||||
commit e74a8f2edb92cb690b467cea0ab652c509e9f624 upstream.
|
||||
|
||||
Commit f44f7f96a20a ("RTC: Initialize kernel state from RTC") introduced a
|
||||
potential infinite loop. If an alarm time contains a wildcard month and
|
||||
an invalid day (> 31), or a wildcard year and an invalid month (>= 12),
|
||||
the loop searching for the next matching date will never terminate. Treat
|
||||
the invalid values as wildcards.
|
||||
|
||||
Fixes <http://bugs.debian.org/646429>, <http://bugs.debian.org/653331>
|
||||
|
||||
Reported-by: leo weppelman <leoweppelman@googlemail.com>
|
||||
Reported-by: "P. van Gaans" <mailme667@yahoo.co.uk>
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
|
||||
Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||
Cc: Marcelo Roberto Jimenez <mroberto@cpti.cetuc.puc-rio.br>
|
||||
Cc: Thomas Gleixner <tglx@linutronix.de>
|
||||
Cc: John Stultz <john.stultz@linaro.org>
|
||||
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/rtc/interface.c | 4 ++--
|
||||
1 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
|
||||
index 8e28625..8a1c031 100644
|
||||
--- a/drivers/rtc/interface.c
|
||||
+++ b/drivers/rtc/interface.c
|
||||
@@ -228,11 +228,11 @@ int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
|
||||
alarm->time.tm_hour = now.tm_hour;
|
||||
|
||||
/* For simplicity, only support date rollover for now */
|
||||
- if (alarm->time.tm_mday == -1) {
|
||||
+ if (alarm->time.tm_mday < 1 || alarm->time.tm_mday > 31) {
|
||||
alarm->time.tm_mday = now.tm_mday;
|
||||
missing = day;
|
||||
}
|
||||
- if (alarm->time.tm_mon == -1) {
|
||||
+ if ((unsigned)alarm->time.tm_mon >= 12) {
|
||||
alarm->time.tm_mon = now.tm_mon;
|
||||
if (missing == none)
|
||||
missing = month;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
From 90d3fbe7c2f63a83921d15a9bb1f451d03040f9b Mon Sep 17 00:00:00 2001
|
||||
From: Djalal Harouni <tixxdz@opendz.org>
|
||||
Date: Wed, 4 Jan 2012 17:09:52 -0500
|
||||
Subject: [PATCH 006/130] ext4: add missing ext4_resize_end on error paths
|
||||
|
||||
commit 014a1770371a028d22f364718c805f4216911ecd upstream.
|
||||
|
||||
Online resize ioctls 'EXT4_IOC_GROUP_EXTEND' and 'EXT4_IOC_GROUP_ADD'
|
||||
call ext4_resize_begin() to check permissions and to set the
|
||||
EXT4_RESIZING bit lock, they do their work and they must finish with
|
||||
ext4_resize_end() which calls clear_bit_unlock() to unlock and to
|
||||
avoid -EBUSY errors for the next resize operations.
|
||||
|
||||
This patch adds the missing ext4_resize_end() calls on error paths.
|
||||
|
||||
Patch tested.
|
||||
|
||||
Signed-off-by: Djalal Harouni <tixxdz@opendz.org>
|
||||
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
fs/ext4/ioctl.c | 28 ++++++++++++++++++----------
|
||||
1 files changed, 18 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
|
||||
index a567968..ab25f57 100644
|
||||
--- a/fs/ext4/ioctl.c
|
||||
+++ b/fs/ext4/ioctl.c
|
||||
@@ -182,19 +182,22 @@ setversion_out:
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- if (get_user(n_blocks_count, (__u32 __user *)arg))
|
||||
- return -EFAULT;
|
||||
+ if (get_user(n_blocks_count, (__u32 __user *)arg)) {
|
||||
+ err = -EFAULT;
|
||||
+ goto group_extend_out;
|
||||
+ }
|
||||
|
||||
if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
|
||||
EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
|
||||
ext4_msg(sb, KERN_ERR,
|
||||
"Online resizing not supported with bigalloc");
|
||||
- return -EOPNOTSUPP;
|
||||
+ err = -EOPNOTSUPP;
|
||||
+ goto group_extend_out;
|
||||
}
|
||||
|
||||
err = mnt_want_write(filp->f_path.mnt);
|
||||
if (err)
|
||||
- return err;
|
||||
+ goto group_extend_out;
|
||||
|
||||
err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count);
|
||||
if (EXT4_SB(sb)->s_journal) {
|
||||
@@ -204,9 +207,10 @@ setversion_out:
|
||||
}
|
||||
if (err == 0)
|
||||
err = err2;
|
||||
+
|
||||
mnt_drop_write(filp->f_path.mnt);
|
||||
+group_extend_out:
|
||||
ext4_resize_end(sb);
|
||||
-
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -267,19 +271,22 @@ mext_out:
|
||||
return err;
|
||||
|
||||
if (copy_from_user(&input, (struct ext4_new_group_input __user *)arg,
|
||||
- sizeof(input)))
|
||||
- return -EFAULT;
|
||||
+ sizeof(input))) {
|
||||
+ err = -EFAULT;
|
||||
+ goto group_add_out;
|
||||
+ }
|
||||
|
||||
if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
|
||||
EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
|
||||
ext4_msg(sb, KERN_ERR,
|
||||
"Online resizing not supported with bigalloc");
|
||||
- return -EOPNOTSUPP;
|
||||
+ err = -EOPNOTSUPP;
|
||||
+ goto group_add_out;
|
||||
}
|
||||
|
||||
err = mnt_want_write(filp->f_path.mnt);
|
||||
if (err)
|
||||
- return err;
|
||||
+ goto group_add_out;
|
||||
|
||||
err = ext4_group_add(sb, &input);
|
||||
if (EXT4_SB(sb)->s_journal) {
|
||||
@@ -289,9 +296,10 @@ mext_out:
|
||||
}
|
||||
if (err == 0)
|
||||
err = err2;
|
||||
+
|
||||
mnt_drop_write(filp->f_path.mnt);
|
||||
+group_add_out:
|
||||
ext4_resize_end(sb);
|
||||
-
|
||||
return err;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
From 149672e502af36fdb60960faaf2ca3bdde96bd5e Mon Sep 17 00:00:00 2001
|
||||
From: Xi Wang <xi.wang@gmail.com>
|
||||
Date: Tue, 10 Jan 2012 11:51:10 -0500
|
||||
Subject: [PATCH 007/130] ext4: fix undefined behavior in
|
||||
ext4_fill_flex_info()
|
||||
|
||||
commit d50f2ab6f050311dbf7b8f5501b25f0bf64a439b upstream.
|
||||
|
||||
Commit 503358ae01b70ce6909d19dd01287093f6b6271c ("ext4: avoid divide by
|
||||
zero when trying to mount a corrupted file system") fixes CVE-2009-4307
|
||||
by performing a sanity check on s_log_groups_per_flex, since it can be
|
||||
set to a bogus value by an attacker.
|
||||
|
||||
sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex;
|
||||
groups_per_flex = 1 << sbi->s_log_groups_per_flex;
|
||||
|
||||
if (groups_per_flex < 2) { ... }
|
||||
|
||||
This patch fixes two potential issues in the previous commit.
|
||||
|
||||
1) The sanity check might only work on architectures like PowerPC.
|
||||
On x86, 5 bits are used for the shifting amount. That means, given a
|
||||
large s_log_groups_per_flex value like 36, groups_per_flex = 1 << 36
|
||||
is essentially 1 << 4 = 16, rather than 0. This will bypass the check,
|
||||
leaving s_log_groups_per_flex and groups_per_flex inconsistent.
|
||||
|
||||
2) The sanity check relies on undefined behavior, i.e., oversized shift.
|
||||
A standard-confirming C compiler could rewrite the check in unexpected
|
||||
ways. Consider the following equivalent form, assuming groups_per_flex
|
||||
is unsigned for simplicity.
|
||||
|
||||
groups_per_flex = 1 << sbi->s_log_groups_per_flex;
|
||||
if (groups_per_flex == 0 || groups_per_flex == 1) {
|
||||
|
||||
We compile the code snippet using Clang 3.0 and GCC 4.6. Clang will
|
||||
completely optimize away the check groups_per_flex == 0, leaving the
|
||||
patched code as vulnerable as the original. GCC keeps the check, but
|
||||
there is no guarantee that future versions will do the same.
|
||||
|
||||
Signed-off-by: Xi Wang <xi.wang@gmail.com>
|
||||
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
fs/ext4/super.c | 7 +++----
|
||||
1 files changed, 3 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
|
||||
index 3e1329e..9281dbe 100644
|
||||
--- a/fs/ext4/super.c
|
||||
+++ b/fs/ext4/super.c
|
||||
@@ -2006,17 +2006,16 @@ static int ext4_fill_flex_info(struct super_block *sb)
|
||||
struct ext4_group_desc *gdp = NULL;
|
||||
ext4_group_t flex_group_count;
|
||||
ext4_group_t flex_group;
|
||||
- int groups_per_flex = 0;
|
||||
+ unsigned int groups_per_flex = 0;
|
||||
size_t size;
|
||||
int i;
|
||||
|
||||
sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex;
|
||||
- groups_per_flex = 1 << sbi->s_log_groups_per_flex;
|
||||
-
|
||||
- if (groups_per_flex < 2) {
|
||||
+ if (sbi->s_log_groups_per_flex < 1 || sbi->s_log_groups_per_flex > 31) {
|
||||
sbi->s_log_groups_per_flex = 0;
|
||||
return 1;
|
||||
}
|
||||
+ groups_per_flex = 1 << sbi->s_log_groups_per_flex;
|
||||
|
||||
/* We allocate both existing and potentially added groups */
|
||||
flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) +
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
From 77b0511fab25f495a30242f4b2fd940e71ce11ad Mon Sep 17 00:00:00 2001
|
||||
From: Karsten Wiese <fzu@wemgehoertderstaat.de>
|
||||
Date: Fri, 30 Dec 2011 01:42:01 +0100
|
||||
Subject: [PATCH 008/130] ALSA: snd-usb-us122l: Delete calls to
|
||||
preempt_disable
|
||||
|
||||
commit d0f3a2eb9062560bebca8b923424f3ca02a331ba upstream.
|
||||
|
||||
They are not needed here.
|
||||
|
||||
Signed-off-by: Karsten Wiese <fzu@wemgehoertderstaat.de>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
sound/usb/usx2y/usb_stream.c | 6 ++----
|
||||
1 files changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
|
||||
index c400ade..1e7a47a 100644
|
||||
--- a/sound/usb/usx2y/usb_stream.c
|
||||
+++ b/sound/usb/usx2y/usb_stream.c
|
||||
@@ -674,7 +674,7 @@ dotry:
|
||||
inurb->transfer_buffer_length =
|
||||
inurb->number_of_packets *
|
||||
inurb->iso_frame_desc[0].length;
|
||||
- preempt_disable();
|
||||
+
|
||||
if (u == 0) {
|
||||
int now;
|
||||
struct usb_device *dev = inurb->dev;
|
||||
@@ -686,19 +686,17 @@ dotry:
|
||||
}
|
||||
err = usb_submit_urb(inurb, GFP_ATOMIC);
|
||||
if (err < 0) {
|
||||
- preempt_enable();
|
||||
snd_printk(KERN_ERR"usb_submit_urb(sk->inurb[%i])"
|
||||
" returned %i\n", u, err);
|
||||
return err;
|
||||
}
|
||||
err = usb_submit_urb(outurb, GFP_ATOMIC);
|
||||
if (err < 0) {
|
||||
- preempt_enable();
|
||||
snd_printk(KERN_ERR"usb_submit_urb(sk->outurb[%i])"
|
||||
" returned %i\n", u, err);
|
||||
return err;
|
||||
}
|
||||
- preempt_enable();
|
||||
+
|
||||
if (inurb->start_frame != outurb->start_frame) {
|
||||
snd_printd(KERN_DEBUG
|
||||
"u[%i] start_frames differ in:%u out:%u\n",
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
From c237e8b240ea09139d387e89f7474fbcd2b4bd0c Mon Sep 17 00:00:00 2001
|
||||
From: David Henningsson <david.henningsson@canonical.com>
|
||||
Date: Mon, 2 Jan 2012 12:40:15 +0100
|
||||
Subject: [PATCH 009/130] ALSA: HDA: Fix master control for Cirrus Logic 421X
|
||||
|
||||
commit 40d03e63e91af8ddccdfd5a536cc2a6e51433e1d upstream.
|
||||
|
||||
The control name "HP/Speakers" is non-standard, and since there is
|
||||
only one DAC on this chip there is no need for a virtual master
|
||||
anyway.
|
||||
|
||||
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
sound/pci/hda/patch_cirrus.c | 13 +------------
|
||||
1 files changed, 1 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
|
||||
index 70a7abd..f55ceb6 100644
|
||||
--- a/sound/pci/hda/patch_cirrus.c
|
||||
+++ b/sound/pci/hda/patch_cirrus.c
|
||||
@@ -1771,30 +1771,19 @@ static int build_cs421x_output(struct hda_codec *codec)
|
||||
struct auto_pin_cfg *cfg = &spec->autocfg;
|
||||
struct snd_kcontrol *kctl;
|
||||
int err;
|
||||
- char *name = "HP/Speakers";
|
||||
+ char *name = "Master";
|
||||
|
||||
fix_volume_caps(codec, dac);
|
||||
- if (!spec->vmaster_sw) {
|
||||
- err = add_vmaster(codec, dac);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
- }
|
||||
|
||||
err = add_mute(codec, name, 0,
|
||||
HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
|
||||
if (err < 0)
|
||||
return err;
|
||||
- err = snd_ctl_add_slave(spec->vmaster_sw, kctl);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
|
||||
err = add_volume(codec, name, 0,
|
||||
HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
|
||||
if (err < 0)
|
||||
return err;
|
||||
- err = snd_ctl_add_slave(spec->vmaster_vol, kctl);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
|
||||
if (cfg->speaker_outs) {
|
||||
err = snd_hda_ctl_add(codec, 0,
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
From d08570c3c46be8ea5797897e7ae4df418d404c2d Mon Sep 17 00:00:00 2001
|
||||
From: David Henningsson <david.henningsson@canonical.com>
|
||||
Date: Mon, 2 Jan 2012 12:40:16 +0100
|
||||
Subject: [PATCH 010/130] ALSA: HDA: Fix automute for Cirrus Logic 421x
|
||||
|
||||
commit 78e2a928e377d5124932d4399c6c581908b027a0 upstream.
|
||||
|
||||
There was a bug in the automute logic causing speakers not to
|
||||
mute when headphones were plugged in.
|
||||
|
||||
Tested-by: Hsin-Yi Chen <hychen@canonical.com>
|
||||
Signed-off-by: David Henningsson <david.henningsson@canonical.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
sound/pci/hda/patch_cirrus.c | 14 ++++++--------
|
||||
1 files changed, 6 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
|
||||
index f55ceb6..5b0a9bb 100644
|
||||
--- a/sound/pci/hda/patch_cirrus.c
|
||||
+++ b/sound/pci/hda/patch_cirrus.c
|
||||
@@ -920,16 +920,14 @@ static void cs_automute(struct hda_codec *codec)
|
||||
|
||||
/* mute speakers if spdif or hp jack is plugged in */
|
||||
for (i = 0; i < cfg->speaker_outs; i++) {
|
||||
+ int pin_ctl = hp_present ? 0 : PIN_OUT;
|
||||
+ /* detect on spdif is specific to CS421x */
|
||||
+ if (spdif_present && (spec->vendor_nid == CS421X_VENDOR_NID))
|
||||
+ pin_ctl = 0;
|
||||
+
|
||||
nid = cfg->speaker_pins[i];
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
- AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
- hp_present ? 0 : PIN_OUT);
|
||||
- /* detect on spdif is specific to CS421x */
|
||||
- if (spec->vendor_nid == CS421X_VENDOR_NID) {
|
||||
- snd_hda_codec_write(codec, nid, 0,
|
||||
- AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
- spdif_present ? 0 : PIN_OUT);
|
||||
- }
|
||||
+ AC_VERB_SET_PIN_WIDGET_CONTROL, pin_ctl);
|
||||
}
|
||||
if (spec->gpio_eapd_hp) {
|
||||
unsigned int gpio = hp_present ?
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
From 37a4221e9e94eb1841d5367baba68e31b0c29d4b Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Hofman <pavel.hofman@ivitera.com>
|
||||
Date: Thu, 5 Jan 2012 23:05:18 +0100
|
||||
Subject: [PATCH 011/130] ALSA: ice1724 - Check for ac97 to avoid kernel oops
|
||||
|
||||
commit e7848163aa2a649d9065f230fadff80dc3519775 upstream.
|
||||
|
||||
Cards with identical PCI ids but no AC97 config in EEPROM do not have
|
||||
the ac97 field initialized. We must check for this case to avoid kernel oops.
|
||||
|
||||
Signed-off-by: Pavel Hofman <pavel.hofman@ivitera.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
sound/pci/ice1712/amp.c | 7 +++++--
|
||||
1 files changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c
|
||||
index e328cfb..e525da2 100644
|
||||
--- a/sound/pci/ice1712/amp.c
|
||||
+++ b/sound/pci/ice1712/amp.c
|
||||
@@ -68,8 +68,11 @@ static int __devinit snd_vt1724_amp_init(struct snd_ice1712 *ice)
|
||||
|
||||
static int __devinit snd_vt1724_amp_add_controls(struct snd_ice1712 *ice)
|
||||
{
|
||||
- /* we use pins 39 and 41 of the VT1616 for left and right read outputs */
|
||||
- snd_ac97_write_cache(ice->ac97, 0x5a, snd_ac97_read(ice->ac97, 0x5a) & ~0x8000);
|
||||
+ if (ice->ac97)
|
||||
+ /* we use pins 39 and 41 of the VT1616 for left and right
|
||||
+ read outputs */
|
||||
+ snd_ac97_write_cache(ice->ac97, 0x5a,
|
||||
+ snd_ac97_read(ice->ac97, 0x5a) & ~0x8000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
From 3997412715c72bd24b2433c841b63590ec175755 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Mon, 9 Jan 2012 11:37:20 +0100
|
||||
Subject: [PATCH 012/130] ALSA: usb-audio - Avoid flood of frame-active debug
|
||||
messages
|
||||
|
||||
commit 80c8a2a372599e604b04a9c568952fe39cd1851d upstream.
|
||||
|
||||
With some buggy devices, the usb-audio driver may give "frame xxx active"
|
||||
kernel messages too often. Better to keep it as debug-only using
|
||||
snd_printdd(), and also add the rate-limit for avoiding floods.
|
||||
|
||||
Bugzilla: https://bugzilla.novell.com/show_bug.cgi?id=738681
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
sound/usb/endpoint.c | 5 +++--
|
||||
1 files changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
|
||||
index 81c6ede..08dcce5 100644
|
||||
--- a/sound/usb/endpoint.c
|
||||
+++ b/sound/usb/endpoint.c
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/init.h>
|
||||
+#include <linux/ratelimit.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb/audio.h>
|
||||
|
||||
@@ -458,8 +459,8 @@ static int retire_capture_urb(struct snd_usb_substream *subs,
|
||||
|
||||
for (i = 0; i < urb->number_of_packets; i++) {
|
||||
cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
|
||||
- if (urb->iso_frame_desc[i].status) {
|
||||
- snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
|
||||
+ if (urb->iso_frame_desc[i].status && printk_ratelimit()) {
|
||||
+ snd_printdd("frame %d active: %d\n", i, urb->iso_frame_desc[i].status);
|
||||
// continue;
|
||||
}
|
||||
bytes = urb->iso_frame_desc[i].actual_length;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
From 82b777e29dcdaa78de5834c88eec7d6733f7aaff Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Tue, 10 Jan 2012 08:59:56 +0100
|
||||
Subject: [PATCH 013/130] ALSA: hda - Use auto-parser for HP laptops with
|
||||
cx20459 codec
|
||||
|
||||
commit de4da59e480cdf1075b33dbaf8078fc87bc52241 upstream.
|
||||
|
||||
These laptops can work well with the auto-parser and their BIOS setups,
|
||||
and in addition, the auto-parser fixes the problem with S3/S4 where
|
||||
the unsol event handling is killed after resume due to fallback to the
|
||||
single-cmd mode.
|
||||
|
||||
Bugzilla: https://bugzilla.novell.com/show_bug.cgi?id=740115
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
sound/pci/hda/patch_conexant.c | 2 --
|
||||
1 files changed, 0 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
|
||||
index 0de2119..7072251 100644
|
||||
--- a/sound/pci/hda/patch_conexant.c
|
||||
+++ b/sound/pci/hda/patch_conexant.c
|
||||
@@ -1120,8 +1120,6 @@ static const char * const cxt5045_models[CXT5045_MODELS] = {
|
||||
|
||||
static const struct snd_pci_quirk cxt5045_cfg_tbl[] = {
|
||||
SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
|
||||
- SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
|
||||
- CXT5045_LAPTOP_HPSENSE),
|
||||
SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE),
|
||||
SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ),
|
||||
SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE),
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
From b347c4f831da8a0e1498b0947e7a334e9113cd83 Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Tue, 10 Jan 2012 12:41:22 +0100
|
||||
Subject: [PATCH 014/130] ALSA: hda - Return the error from get_wcaps_type()
|
||||
for invalid NIDs
|
||||
|
||||
commit 3a90274de3548ebb2aabfbf488cea8e275a73dc6 upstream.
|
||||
|
||||
When an invalid NID is given, get_wcaps() returns zero as the error,
|
||||
but get_wcaps_type() takes it as the normal value and returns a bogus
|
||||
AC_WID_AUD_OUT value. This confuses the parser.
|
||||
|
||||
With this patch, get_wcaps_type() returns -1 when value 0 is given,
|
||||
i.e. an invalid NID is passed to get_wcaps().
|
||||
|
||||
Bugzilla: https://bugzilla.novell.com/show_bug.cgi?id=740118
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
sound/pci/hda/hda_local.h | 7 ++++++-
|
||||
sound/pci/hda/hda_proc.c | 2 ++
|
||||
2 files changed, 8 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
|
||||
index 618ddad..368f0c5 100644
|
||||
--- a/sound/pci/hda/hda_local.h
|
||||
+++ b/sound/pci/hda/hda_local.h
|
||||
@@ -487,7 +487,12 @@ static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid)
|
||||
}
|
||||
|
||||
/* get the widget type from widget capability bits */
|
||||
-#define get_wcaps_type(wcaps) (((wcaps) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT)
|
||||
+static inline int get_wcaps_type(unsigned int wcaps)
|
||||
+{
|
||||
+ if (!wcaps)
|
||||
+ return -1; /* invalid type */
|
||||
+ return (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
|
||||
+}
|
||||
|
||||
static inline unsigned int get_wcaps_channels(u32 wcaps)
|
||||
{
|
||||
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
|
||||
index 2c981b5..254ab52 100644
|
||||
--- a/sound/pci/hda/hda_proc.c
|
||||
+++ b/sound/pci/hda/hda_proc.c
|
||||
@@ -54,6 +54,8 @@ static const char *get_wid_type_name(unsigned int wid_value)
|
||||
[AC_WID_BEEP] = "Beep Generator Widget",
|
||||
[AC_WID_VENDOR] = "Vendor Defined Widget",
|
||||
};
|
||||
+ if (wid_value == -1)
|
||||
+ return "UNKNOWN Widget";
|
||||
wid_value &= 0xf;
|
||||
if (names[wid_value])
|
||||
return names[wid_value];
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
From ea14c41fb5a54a4f2089c97f85c399965415871a Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Tue, 10 Jan 2012 15:16:02 +0100
|
||||
Subject: [PATCH 015/130] ALSA: hda - Fix the detection of "Loopback Mixing"
|
||||
control for VIA codecs
|
||||
|
||||
commit 4808d12d1dddb046ec86425e5f6766f02e950292 upstream.
|
||||
|
||||
Currently the driver checks only the out_mix_path[] for the primary
|
||||
output route for judging whether to create the loopback-mixing control
|
||||
or not. But, there are cases where aamix-routing is available only on
|
||||
headphone or speaker paths but not on the primary output path. So, the
|
||||
driver ignores such cases inappropriately.
|
||||
|
||||
This patch fixes the check of the loopback-mixing control by testing
|
||||
all mix-routing paths.
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
sound/pci/hda/patch_via.c | 5 ++++-
|
||||
1 files changed, 4 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
|
||||
index b513762..8d69e59 100644
|
||||
--- a/sound/pci/hda/patch_via.c
|
||||
+++ b/sound/pci/hda/patch_via.c
|
||||
@@ -2200,7 +2200,10 @@ static int via_auto_create_loopback_switch(struct hda_codec *codec)
|
||||
{
|
||||
struct via_spec *spec = codec->spec;
|
||||
|
||||
- if (!spec->aa_mix_nid || !spec->out_mix_path.depth)
|
||||
+ if (!spec->aa_mix_nid)
|
||||
+ return 0; /* no loopback switching available */
|
||||
+ if (!(spec->out_mix_path.depth || spec->hp_mix_path.depth ||
|
||||
+ spec->speaker_path.depth))
|
||||
return 0; /* no loopback switching available */
|
||||
if (!via_clone_control(spec, &via_aamix_ctl_enum))
|
||||
return -ENOMEM;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
From 53eb674241d25d1496c966cd5f140b0bb213dbdc Mon Sep 17 00:00:00 2001
|
||||
From: Takashi Iwai <tiwai@suse.de>
|
||||
Date: Wed, 11 Jan 2012 12:34:11 +0100
|
||||
Subject: [PATCH 016/130] ALSA: hda - Fix the lost power-setup of seconary
|
||||
pins after PM resume
|
||||
|
||||
commit f2cbba7602383cd9cdd21f0a5d0b8bd1aad47b33 upstream.
|
||||
|
||||
When multiple headphone or other detectable output pins are present,
|
||||
the power-map has to be updated after resume appropriately, but the
|
||||
current driver doesn't check all pins but only the first pin (since
|
||||
it's enough to check it for the mute-behavior). This resulted in the
|
||||
silent output from the secondary outputs after PM resume.
|
||||
|
||||
This patch fixes the problem by checking all pins at (re-)init time.
|
||||
|
||||
Bugzilla: https://bugzilla.novell.com/show_bug.cgi?id=740347
|
||||
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
sound/pci/hda/patch_sigmatel.c | 36 +++++++++++++++++++++++-------------
|
||||
1 files changed, 23 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
|
||||
index 616678f..a87b260 100644
|
||||
--- a/sound/pci/hda/patch_sigmatel.c
|
||||
+++ b/sound/pci/hda/patch_sigmatel.c
|
||||
@@ -4326,6 +4326,27 @@ static void stac_store_hints(struct hda_codec *codec)
|
||||
}
|
||||
}
|
||||
|
||||
+static void stac_issue_unsol_events(struct hda_codec *codec, int num_pins,
|
||||
+ const hda_nid_t *pins)
|
||||
+{
|
||||
+ while (num_pins--)
|
||||
+ stac_issue_unsol_event(codec, *pins++);
|
||||
+}
|
||||
+
|
||||
+/* fake event to set up pins */
|
||||
+static void stac_fake_hp_events(struct hda_codec *codec)
|
||||
+{
|
||||
+ struct sigmatel_spec *spec = codec->spec;
|
||||
+
|
||||
+ if (spec->autocfg.hp_outs)
|
||||
+ stac_issue_unsol_events(codec, spec->autocfg.hp_outs,
|
||||
+ spec->autocfg.hp_pins);
|
||||
+ if (spec->autocfg.line_outs &&
|
||||
+ spec->autocfg.line_out_pins[0] != spec->autocfg.hp_pins[0])
|
||||
+ stac_issue_unsol_events(codec, spec->autocfg.line_outs,
|
||||
+ spec->autocfg.line_out_pins);
|
||||
+}
|
||||
+
|
||||
static int stac92xx_init(struct hda_codec *codec)
|
||||
{
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
@@ -4376,10 +4397,7 @@ static int stac92xx_init(struct hda_codec *codec)
|
||||
stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
|
||||
AC_PINCTL_OUT_EN);
|
||||
/* fake event to set up pins */
|
||||
- if (cfg->hp_pins[0])
|
||||
- stac_issue_unsol_event(codec, cfg->hp_pins[0]);
|
||||
- else if (cfg->line_out_pins[0])
|
||||
- stac_issue_unsol_event(codec, cfg->line_out_pins[0]);
|
||||
+ stac_fake_hp_events(codec);
|
||||
} else {
|
||||
stac92xx_auto_init_multi_out(codec);
|
||||
stac92xx_auto_init_hp_out(codec);
|
||||
@@ -5028,19 +5046,11 @@ static void stac927x_proc_hook(struct snd_info_buffer *buffer,
|
||||
#ifdef CONFIG_PM
|
||||
static int stac92xx_resume(struct hda_codec *codec)
|
||||
{
|
||||
- struct sigmatel_spec *spec = codec->spec;
|
||||
-
|
||||
stac92xx_init(codec);
|
||||
snd_hda_codec_resume_amp(codec);
|
||||
snd_hda_codec_resume_cache(codec);
|
||||
/* fake event to set up pins again to override cached values */
|
||||
- if (spec->hp_detect) {
|
||||
- if (spec->autocfg.hp_pins[0])
|
||||
- stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]);
|
||||
- else if (spec->autocfg.line_out_pins[0])
|
||||
- stac_issue_unsol_event(codec,
|
||||
- spec->autocfg.line_out_pins[0]);
|
||||
- }
|
||||
+ stac_fake_hp_events(codec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
From d69882b450293b61af0820e75dc1bfb8823c58bd Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
|
||||
Date: Fri, 23 Dec 2011 20:32:18 +0100
|
||||
Subject: [PATCH 017/130] drm/radeon/kms: workaround invalid AVI infoframe
|
||||
checksum issue
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
commit 92db7f6c860b8190571a9dc1fcbc16d003422fe8 upstream.
|
||||
|
||||
This change was verified to fix both issues with no video I've
|
||||
investigated. I've also checked checksum calculation with fglrx on:
|
||||
RV620, HD54xx, HD5450, HD6310, HD6320.
|
||||
|
||||
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/gpu/drm/radeon/r600_hdmi.c | 7 +++++++
|
||||
1 files changed, 7 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
|
||||
index f5ac7e7..c45d921 100644
|
||||
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
|
||||
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
|
||||
@@ -196,6 +196,13 @@ static void r600_hdmi_videoinfoframe(
|
||||
frame[0xD] = (right_bar >> 8);
|
||||
|
||||
r600_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame);
|
||||
+ /* Our header values (type, version, length) should be alright, Intel
|
||||
+ * is using the same. Checksum function also seems to be OK, it works
|
||||
+ * fine for audio infoframe. However calculated value is always lower
|
||||
+ * by 2 in comparison to fglrx. It breaks displaying anything in case
|
||||
+ * of TVs that strictly check the checksum. Hack it manually here to
|
||||
+ * workaround this issue. */
|
||||
+ frame[0x0] += 2;
|
||||
|
||||
WREG32(offset+R600_HDMI_VIDEOINFOFRAME_0,
|
||||
frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
From 056276f2509223f4f07a0778f1f1b398fdc8ae87 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Deucher <alexander.deucher@amd.com>
|
||||
Date: Tue, 3 Jan 2012 09:48:38 -0500
|
||||
Subject: [PATCH 018/130] drm/radeon/kms: disable writeback on pre-R300 asics
|
||||
|
||||
commit 28eebb703e28bc455ba704adb1026f76649b768c upstream.
|
||||
|
||||
We often end up missing fences on older asics with
|
||||
writeback enabled which leads to delays in the userspace
|
||||
accel code, so just disable it by default on those asics.
|
||||
|
||||
Reported-by: Helge Deller <deller@gmx.de>
|
||||
Reported-by: Dave Airlie <airlied@redhat.com>
|
||||
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/gpu/drm/radeon/radeon_device.c | 5 ++++-
|
||||
1 files changed, 4 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
|
||||
index c4d00a1..9b39145 100644
|
||||
--- a/drivers/gpu/drm/radeon/radeon_device.c
|
||||
+++ b/drivers/gpu/drm/radeon/radeon_device.c
|
||||
@@ -224,8 +224,11 @@ int radeon_wb_init(struct radeon_device *rdev)
|
||||
if (radeon_no_wb == 1)
|
||||
rdev->wb.enabled = false;
|
||||
else {
|
||||
- /* often unreliable on AGP */
|
||||
if (rdev->flags & RADEON_IS_AGP) {
|
||||
+ /* often unreliable on AGP */
|
||||
+ rdev->wb.enabled = false;
|
||||
+ } else if (rdev->family < CHIP_R300) {
|
||||
+ /* often unreliable on pre-r300 */
|
||||
rdev->wb.enabled = false;
|
||||
} else {
|
||||
rdev->wb.enabled = true;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
From a4064a0d9fab7c0a6aa4b6bf170d6ffaed93601a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daenzer@amd.com>
|
||||
Date: Thu, 5 Jan 2012 18:42:17 +0100
|
||||
Subject: [PATCH 019/130] radeon: Fix disabling PCI bus mastering on big
|
||||
endian hosts.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
commit 3df96909b75835d487a9178761622b0cbd7310d4 upstream.
|
||||
|
||||
It would previously write basically random bits to PCI configuration space...
|
||||
Not very surprising that the GPU tended to stop responding completely. The
|
||||
resulting MCE even froze the whole machine sometimes.
|
||||
|
||||
Now resetting the GPU after a lockup has at least a fighting chance of
|
||||
succeeding.
|
||||
|
||||
Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
|
||||
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/gpu/drm/radeon/r100.c | 5 +++--
|
||||
drivers/gpu/drm/radeon/rs600.c | 4 ++--
|
||||
2 files changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
|
||||
index bfc08f6..31b0d1a 100644
|
||||
--- a/drivers/gpu/drm/radeon/r100.c
|
||||
+++ b/drivers/gpu/drm/radeon/r100.c
|
||||
@@ -2177,6 +2177,7 @@ bool r100_gpu_is_lockup(struct radeon_device *rdev)
|
||||
void r100_bm_disable(struct radeon_device *rdev)
|
||||
{
|
||||
u32 tmp;
|
||||
+ u16 tmp16;
|
||||
|
||||
/* disable bus mastering */
|
||||
tmp = RREG32(R_000030_BUS_CNTL);
|
||||
@@ -2187,8 +2188,8 @@ void r100_bm_disable(struct radeon_device *rdev)
|
||||
WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000040);
|
||||
tmp = RREG32(RADEON_BUS_CNTL);
|
||||
mdelay(1);
|
||||
- pci_read_config_word(rdev->pdev, 0x4, (u16*)&tmp);
|
||||
- pci_write_config_word(rdev->pdev, 0x4, tmp & 0xFFFB);
|
||||
+ pci_read_config_word(rdev->pdev, 0x4, &tmp16);
|
||||
+ pci_write_config_word(rdev->pdev, 0x4, tmp16 & 0xFFFB);
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
|
||||
index b1053d6..c259e21 100644
|
||||
--- a/drivers/gpu/drm/radeon/rs600.c
|
||||
+++ b/drivers/gpu/drm/radeon/rs600.c
|
||||
@@ -324,10 +324,10 @@ void rs600_hpd_fini(struct radeon_device *rdev)
|
||||
|
||||
void rs600_bm_disable(struct radeon_device *rdev)
|
||||
{
|
||||
- u32 tmp;
|
||||
+ u16 tmp;
|
||||
|
||||
/* disable bus mastering */
|
||||
- pci_read_config_word(rdev->pdev, 0x4, (u16*)&tmp);
|
||||
+ pci_read_config_word(rdev->pdev, 0x4, &tmp);
|
||||
pci_write_config_word(rdev->pdev, 0x4, tmp & 0xFFFB);
|
||||
mdelay(1);
|
||||
}
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
From df673b323fa5ef227649ad218343f244261c0611 Mon Sep 17 00:00:00 2001
|
||||
From: Boaz Harrosh <bharrosh@panasas.com>
|
||||
Date: Fri, 6 Jan 2012 09:28:12 +0200
|
||||
Subject: [PATCH 020/130] pnfs-obj: pNFS errors are communicated on
|
||||
iodata->pnfs_error
|
||||
|
||||
commit 5c0b4129c07b902b27d3f3ebc087757f534a3abd upstream.
|
||||
|
||||
Some time along the way pNFS IO errors were switched to
|
||||
communicate with a special iodata->pnfs_error member instead
|
||||
of the regular RPC members. But objlayout was not switched
|
||||
over.
|
||||
|
||||
Fix that!
|
||||
Without this fix any IO error is hanged, because IO is not
|
||||
switched to MDS and pages are never cleared or read.
|
||||
|
||||
[Applies to 3.2.0. Same bug different patch for 3.1/0 Kernels]
|
||||
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
|
||||
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
fs/nfs/objlayout/objlayout.c | 4 ++++
|
||||
1 files changed, 4 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/fs/nfs/objlayout/objlayout.c b/fs/nfs/objlayout/objlayout.c
|
||||
index 72074e3..b3c2903 100644
|
||||
--- a/fs/nfs/objlayout/objlayout.c
|
||||
+++ b/fs/nfs/objlayout/objlayout.c
|
||||
@@ -254,6 +254,8 @@ objlayout_read_done(struct objlayout_io_res *oir, ssize_t status, bool sync)
|
||||
oir->status = rdata->task.tk_status = status;
|
||||
if (status >= 0)
|
||||
rdata->res.count = status;
|
||||
+ else
|
||||
+ rdata->pnfs_error = status;
|
||||
objlayout_iodone(oir);
|
||||
/* must not use oir after this point */
|
||||
|
||||
@@ -334,6 +336,8 @@ objlayout_write_done(struct objlayout_io_res *oir, ssize_t status, bool sync)
|
||||
if (status >= 0) {
|
||||
wdata->res.count = status;
|
||||
wdata->verf.committed = oir->committed;
|
||||
+ } else {
|
||||
+ wdata->pnfs_error = status;
|
||||
}
|
||||
objlayout_iodone(oir);
|
||||
/* must not use oir after this point */
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
From 9c85d688c42a6feb8f72204730514ae658854828 Mon Sep 17 00:00:00 2001
|
||||
From: Boaz Harrosh <bharrosh@panasas.com>
|
||||
Date: Fri, 6 Jan 2012 09:31:20 +0200
|
||||
Subject: [PATCH 021/130] pnfs-obj: Must return layout on IO error
|
||||
|
||||
commit fe0fe83585f88346557868a803a479dfaaa0688a upstream.
|
||||
|
||||
As mandated by the standard. In case of an IO error, a pNFS
|
||||
objects layout driver must return it's layout. This is because
|
||||
all device errors are reported to the server as part of the
|
||||
layout return buffer.
|
||||
|
||||
This is implemented the same way PNFS_LAYOUTRET_ON_SETATTR
|
||||
is done, through a bit flag on the pnfs_layoutdriver_type->flags
|
||||
member. The flag is set by the layout driver that wants a
|
||||
layout_return preformed at pnfs_ld_{write,read}_done in case
|
||||
of an error.
|
||||
(Though I have not defined a wrapper like pnfs_ld_layoutret_on_setattr
|
||||
because this code is never called outside of pnfs.c and pnfs IO
|
||||
paths)
|
||||
|
||||
Without this patch 3.[0-2] Kernels leak memory and have an annoying
|
||||
WARN_ON after every IO error utilizing the pnfs-obj driver.
|
||||
|
||||
Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
|
||||
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
fs/nfs/objlayout/objio_osd.c | 3 ++-
|
||||
fs/nfs/pnfs.c | 12 ++++++++++++
|
||||
fs/nfs/pnfs.h | 1 +
|
||||
3 files changed, 15 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c
|
||||
index c807ab9..55d0128 100644
|
||||
--- a/fs/nfs/objlayout/objio_osd.c
|
||||
+++ b/fs/nfs/objlayout/objio_osd.c
|
||||
@@ -551,7 +551,8 @@ static const struct nfs_pageio_ops objio_pg_write_ops = {
|
||||
static struct pnfs_layoutdriver_type objlayout_type = {
|
||||
.id = LAYOUT_OSD2_OBJECTS,
|
||||
.name = "LAYOUT_OSD2_OBJECTS",
|
||||
- .flags = PNFS_LAYOUTRET_ON_SETATTR,
|
||||
+ .flags = PNFS_LAYOUTRET_ON_SETATTR |
|
||||
+ PNFS_LAYOUTRET_ON_ERROR,
|
||||
|
||||
.alloc_layout_hdr = objlayout_alloc_layout_hdr,
|
||||
.free_layout_hdr = objlayout_free_layout_hdr,
|
||||
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
|
||||
index 8e672a2..f881a63 100644
|
||||
--- a/fs/nfs/pnfs.c
|
||||
+++ b/fs/nfs/pnfs.c
|
||||
@@ -1178,6 +1178,15 @@ void pnfs_ld_write_done(struct nfs_write_data *data)
|
||||
put_lseg(data->lseg);
|
||||
data->lseg = NULL;
|
||||
dprintk("pnfs write error = %d\n", data->pnfs_error);
|
||||
+ if (NFS_SERVER(data->inode)->pnfs_curr_ld->flags &
|
||||
+ PNFS_LAYOUTRET_ON_ERROR) {
|
||||
+ /* Don't lo_commit on error, Server will needs to
|
||||
+ * preform a file recovery.
|
||||
+ */
|
||||
+ clear_bit(NFS_INO_LAYOUTCOMMIT,
|
||||
+ &NFS_I(data->inode)->flags);
|
||||
+ pnfs_return_layout(data->inode);
|
||||
+ }
|
||||
}
|
||||
data->mds_ops->rpc_release(data);
|
||||
}
|
||||
@@ -1267,6 +1276,9 @@ static void pnfs_ld_handle_read_error(struct nfs_read_data *data)
|
||||
put_lseg(data->lseg);
|
||||
data->lseg = NULL;
|
||||
dprintk("pnfs write error = %d\n", data->pnfs_error);
|
||||
+ if (NFS_SERVER(data->inode)->pnfs_curr_ld->flags &
|
||||
+ PNFS_LAYOUTRET_ON_ERROR)
|
||||
+ pnfs_return_layout(data->inode);
|
||||
|
||||
nfs_pageio_init_read_mds(&pgio, data->inode);
|
||||
|
||||
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
|
||||
index 1509530..53d593a 100644
|
||||
--- a/fs/nfs/pnfs.h
|
||||
+++ b/fs/nfs/pnfs.h
|
||||
@@ -68,6 +68,7 @@ enum {
|
||||
enum layoutdriver_policy_flags {
|
||||
/* Should the pNFS client commit and return the layout upon a setattr */
|
||||
PNFS_LAYOUTRET_ON_SETATTR = 1 << 0,
|
||||
+ PNFS_LAYOUTRET_ON_ERROR = 1 << 1,
|
||||
};
|
||||
|
||||
struct nfs4_deviceid_node;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
From 1ef216baa398a27c95a9de67f36805cbeea81fe6 Mon Sep 17 00:00:00 2001
|
||||
From: Chuck Lever <chuck.lever@oracle.com>
|
||||
Date: Mon, 5 Dec 2011 15:40:30 -0500
|
||||
Subject: [PATCH 022/130] NFS: Retry mounting NFSROOT
|
||||
|
||||
commit 43717c7daebf10b43f12e68512484b3095bb1ba5 upstream.
|
||||
|
||||
Lukas Razik <linux@razik.name> reports that on his SPARC system,
|
||||
booting with an NFS root file system stopped working after commit
|
||||
56463e50 "NFS: Use super.c for NFSROOT mount option parsing."
|
||||
|
||||
We found that the network switch to which Lukas' client was attached
|
||||
was delaying access to the LAN after the client's NIC driver reported
|
||||
that its link was up. The delay was longer than the timeouts used in
|
||||
the NFS client during mounting.
|
||||
|
||||
NFSROOT worked for Lukas before commit 56463e50 because in those
|
||||
kernels, the client's first operation was an rpcbind request to
|
||||
determine which port the NFS server was listening on. When that
|
||||
request failed after a long timeout, the client simply selected the
|
||||
default NFS port (2049). By that time the switch was allowing access
|
||||
to the LAN, and the mount succeeded.
|
||||
|
||||
Neither of these client behaviors is desirable, so reverting 56463e50
|
||||
is really not a choice. Instead, introduce a mechanism that retries
|
||||
the NFSROOT mount request several times. This is the same tactic that
|
||||
normal user space NFS mounts employ to overcome server and network
|
||||
delays.
|
||||
|
||||
Signed-off-by: Lukas Razik <linux@razik.name>
|
||||
[ cel: match kernel coding style, add proper patch description ]
|
||||
[ cel: add exponential back-off ]
|
||||
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
||||
Tested-by: Lukas Razik <linux@razik.name>
|
||||
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
init/do_mounts.c | 35 +++++++++++++++++++++++++++++++----
|
||||
1 files changed, 31 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/init/do_mounts.c b/init/do_mounts.c
|
||||
index 0f6e1d9..db6e5ee 100644
|
||||
--- a/init/do_mounts.c
|
||||
+++ b/init/do_mounts.c
|
||||
@@ -398,15 +398,42 @@ out:
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ROOT_NFS
|
||||
+
|
||||
+#define NFSROOT_TIMEOUT_MIN 5
|
||||
+#define NFSROOT_TIMEOUT_MAX 30
|
||||
+#define NFSROOT_RETRY_MAX 5
|
||||
+
|
||||
static int __init mount_nfs_root(void)
|
||||
{
|
||||
char *root_dev, *root_data;
|
||||
+ unsigned int timeout;
|
||||
+ int try, err;
|
||||
|
||||
- if (nfs_root_data(&root_dev, &root_data) != 0)
|
||||
- return 0;
|
||||
- if (do_mount_root(root_dev, "nfs", root_mountflags, root_data) != 0)
|
||||
+ err = nfs_root_data(&root_dev, &root_data);
|
||||
+ if (err != 0)
|
||||
return 0;
|
||||
- return 1;
|
||||
+
|
||||
+ /*
|
||||
+ * The server or network may not be ready, so try several
|
||||
+ * times. Stop after a few tries in case the client wants
|
||||
+ * to fall back to other boot methods.
|
||||
+ */
|
||||
+ timeout = NFSROOT_TIMEOUT_MIN;
|
||||
+ for (try = 1; ; try++) {
|
||||
+ err = do_mount_root(root_dev, "nfs",
|
||||
+ root_mountflags, root_data);
|
||||
+ if (err == 0)
|
||||
+ return 1;
|
||||
+ if (try > NFSROOT_RETRY_MAX)
|
||||
+ break;
|
||||
+
|
||||
+ /* Wait, in case the server refused us immediately */
|
||||
+ ssleep(timeout);
|
||||
+ timeout <<= 1;
|
||||
+ if (timeout > NFSROOT_TIMEOUT_MAX)
|
||||
+ timeout = NFSROOT_TIMEOUT_MAX;
|
||||
+ }
|
||||
+ return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
From a4d5a638ff204626f6244b3a316cf8f01ef3e2fa Mon Sep 17 00:00:00 2001
|
||||
From: Andy Adamson <andros@netapp.com>
|
||||
Date: Wed, 9 Nov 2011 13:58:20 -0500
|
||||
Subject: [PATCH 023/130] NFSv4.1: fix backchannel slotid off-by-one bug
|
||||
|
||||
commit 61f2e5106582d02f30b6807e3f9c07463c572ccb upstream.
|
||||
|
||||
Signed-off-by: Andy Adamson <andros@netapp.com>
|
||||
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
fs/nfs/callback_proc.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
|
||||
index 43926ad..54cea8a 100644
|
||||
--- a/fs/nfs/callback_proc.c
|
||||
+++ b/fs/nfs/callback_proc.c
|
||||
@@ -339,7 +339,7 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args)
|
||||
dprintk("%s enter. slotid %d seqid %d\n",
|
||||
__func__, args->csa_slotid, args->csa_sequenceid);
|
||||
|
||||
- if (args->csa_slotid > NFS41_BC_MAX_CALLBACKS)
|
||||
+ if (args->csa_slotid >= NFS41_BC_MAX_CALLBACKS)
|
||||
return htonl(NFS4ERR_BADSLOT);
|
||||
|
||||
slot = tbl->slots + args->csa_slotid;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
From 876118d108ac910a4b4b4384b6d827ef9eb599bb Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Wed, 16 Nov 2011 11:46:31 +1100
|
||||
Subject: [PATCH 024/130] NFS - fix recent breakage to NFS error handling.
|
||||
|
||||
commit 2edb6bc3852c681c0d948245bd55108dc6407604 upstream.
|
||||
|
||||
From c6d615d2b97fe305cbf123a8751ced859dca1d5e Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Wed, 16 Nov 2011 09:39:05 +1100
|
||||
Subject: NFS - fix recent breakage to NFS error handling.
|
||||
|
||||
commit 02c24a82187d5a628c68edfe71ae60dc135cd178 made a small and
|
||||
presumably unintended change to write error handling in NFS.
|
||||
|
||||
Previously an error from filemap_write_and_wait_range would only be of
|
||||
interest if nfs_file_fsync did not return an error. After this commit,
|
||||
an error from filemap_write_and_wait_range would mean that (the rest of)
|
||||
nfs_file_fsync would not even be called.
|
||||
|
||||
This means that:
|
||||
1/ you are more likely to see EIO than e.g. EDQUOT or ENOSPC.
|
||||
2/ NFS_CONTEXT_ERROR_WRITE remains set for longer so more writes are
|
||||
synchronous.
|
||||
|
||||
This patch restores previous behaviour.
|
||||
|
||||
Cc: Josef Bacik <josef@redhat.com>
|
||||
Cc: Jan Kara <jack@suse.cz>
|
||||
Cc: Al Viro <viro@zeniv.linux.org.uk>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
fs/nfs/file.c | 4 ++--
|
||||
1 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
|
||||
index 606ef0f..c43a452 100644
|
||||
--- a/fs/nfs/file.c
|
||||
+++ b/fs/nfs/file.c
|
||||
@@ -272,13 +272,13 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
|
||||
datasync);
|
||||
|
||||
ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
mutex_lock(&inode->i_mutex);
|
||||
|
||||
nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
|
||||
have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
|
||||
status = nfs_commit_inode(inode, FLUSH_SYNC);
|
||||
+ if (status >= 0 && ret < 0)
|
||||
+ status = ret;
|
||||
have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
|
||||
if (have_error)
|
||||
ret = xchg(&ctx->error, 0);
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+313
@@ -0,0 +1,313 @@
|
||||
From ea3a3ed18130c4a0fe0dbdd3f7dabc59a67c5064 Mon Sep 17 00:00:00 2001
|
||||
From: Andy Adamson <andros@netapp.com>
|
||||
Date: Wed, 7 Dec 2011 11:55:27 -0500
|
||||
Subject: [PATCH 025/130] NFSv4: include bitmap in nfsv4 get acl data
|
||||
|
||||
commit bf118a342f10dafe44b14451a1392c3254629a1f upstream.
|
||||
|
||||
The NFSv4 bitmap size is unbounded: a server can return an arbitrary
|
||||
sized bitmap in an FATTR4_WORD0_ACL request. Replace using the
|
||||
nfs4_fattr_bitmap_maxsz as a guess to the maximum bitmask returned by a server
|
||||
with the inclusion of the bitmap (xdr length plus bitmasks) and the acl data
|
||||
xdr length to the (cached) acl page data.
|
||||
|
||||
This is a general solution to commit e5012d1f "NFSv4.1: update
|
||||
nfs4_fattr_bitmap_maxsz" and fixes hitting a BUG_ON in xdr_shrink_bufhead
|
||||
when getting ACLs.
|
||||
|
||||
Fix a bug in decode_getacl that returned -EINVAL on ACLs > page when getxattr
|
||||
was called with a NULL buffer, preventing ACL > PAGE_SIZE from being retrieved.
|
||||
|
||||
Signed-off-by: Andy Adamson <andros@netapp.com>
|
||||
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
fs/nfs/nfs4proc.c | 96 ++++++++++++++++++++++++++------------------
|
||||
fs/nfs/nfs4xdr.c | 31 ++++++++++----
|
||||
include/linux/nfs_xdr.h | 5 ++
|
||||
include/linux/sunrpc/xdr.h | 2 +
|
||||
net/sunrpc/xdr.c | 3 +-
|
||||
5 files changed, 89 insertions(+), 48 deletions(-)
|
||||
|
||||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
|
||||
index d9f4d78..055d702 100644
|
||||
--- a/fs/nfs/nfs4proc.c
|
||||
+++ b/fs/nfs/nfs4proc.c
|
||||
@@ -3430,19 +3430,6 @@ static inline int nfs4_server_supports_acls(struct nfs_server *server)
|
||||
*/
|
||||
#define NFS4ACL_MAXPAGES (XATTR_SIZE_MAX >> PAGE_CACHE_SHIFT)
|
||||
|
||||
-static void buf_to_pages(const void *buf, size_t buflen,
|
||||
- struct page **pages, unsigned int *pgbase)
|
||||
-{
|
||||
- const void *p = buf;
|
||||
-
|
||||
- *pgbase = offset_in_page(buf);
|
||||
- p -= *pgbase;
|
||||
- while (p < buf + buflen) {
|
||||
- *(pages++) = virt_to_page(p);
|
||||
- p += PAGE_CACHE_SIZE;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
static int buf_to_pages_noslab(const void *buf, size_t buflen,
|
||||
struct page **pages, unsigned int *pgbase)
|
||||
{
|
||||
@@ -3539,9 +3526,19 @@ out:
|
||||
nfs4_set_cached_acl(inode, acl);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * The getxattr API returns the required buffer length when called with a
|
||||
+ * NULL buf. The NFSv4 acl tool then calls getxattr again after allocating
|
||||
+ * the required buf. On a NULL buf, we send a page of data to the server
|
||||
+ * guessing that the ACL request can be serviced by a page. If so, we cache
|
||||
+ * up to the page of ACL data, and the 2nd call to getxattr is serviced by
|
||||
+ * the cache. If not so, we throw away the page, and cache the required
|
||||
+ * length. The next getxattr call will then produce another round trip to
|
||||
+ * the server, this time with the input buf of the required size.
|
||||
+ */
|
||||
static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
|
||||
{
|
||||
- struct page *pages[NFS4ACL_MAXPAGES];
|
||||
+ struct page *pages[NFS4ACL_MAXPAGES] = {NULL, };
|
||||
struct nfs_getaclargs args = {
|
||||
.fh = NFS_FH(inode),
|
||||
.acl_pages = pages,
|
||||
@@ -3556,41 +3553,60 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
|
||||
.rpc_argp = &args,
|
||||
.rpc_resp = &res,
|
||||
};
|
||||
- struct page *localpage = NULL;
|
||||
- int ret;
|
||||
+ int ret = -ENOMEM, npages, i, acl_len = 0;
|
||||
|
||||
- if (buflen < PAGE_SIZE) {
|
||||
- /* As long as we're doing a round trip to the server anyway,
|
||||
- * let's be prepared for a page of acl data. */
|
||||
- localpage = alloc_page(GFP_KERNEL);
|
||||
- resp_buf = page_address(localpage);
|
||||
- if (localpage == NULL)
|
||||
- return -ENOMEM;
|
||||
- args.acl_pages[0] = localpage;
|
||||
- args.acl_pgbase = 0;
|
||||
- args.acl_len = PAGE_SIZE;
|
||||
- } else {
|
||||
- resp_buf = buf;
|
||||
- buf_to_pages(buf, buflen, args.acl_pages, &args.acl_pgbase);
|
||||
+ npages = (buflen + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
+ /* As long as we're doing a round trip to the server anyway,
|
||||
+ * let's be prepared for a page of acl data. */
|
||||
+ if (npages == 0)
|
||||
+ npages = 1;
|
||||
+
|
||||
+ for (i = 0; i < npages; i++) {
|
||||
+ pages[i] = alloc_page(GFP_KERNEL);
|
||||
+ if (!pages[i])
|
||||
+ goto out_free;
|
||||
+ }
|
||||
+ if (npages > 1) {
|
||||
+ /* for decoding across pages */
|
||||
+ args.acl_scratch = alloc_page(GFP_KERNEL);
|
||||
+ if (!args.acl_scratch)
|
||||
+ goto out_free;
|
||||
}
|
||||
- ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), &msg, &args.seq_args, &res.seq_res, 0);
|
||||
+ args.acl_len = npages * PAGE_SIZE;
|
||||
+ args.acl_pgbase = 0;
|
||||
+ /* Let decode_getfacl know not to fail if the ACL data is larger than
|
||||
+ * the page we send as a guess */
|
||||
+ if (buf == NULL)
|
||||
+ res.acl_flags |= NFS4_ACL_LEN_REQUEST;
|
||||
+ resp_buf = page_address(pages[0]);
|
||||
+
|
||||
+ dprintk("%s buf %p buflen %ld npages %d args.acl_len %ld\n",
|
||||
+ __func__, buf, buflen, npages, args.acl_len);
|
||||
+ ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode),
|
||||
+ &msg, &args.seq_args, &res.seq_res, 0);
|
||||
if (ret)
|
||||
goto out_free;
|
||||
- if (res.acl_len > args.acl_len)
|
||||
- nfs4_write_cached_acl(inode, NULL, res.acl_len);
|
||||
+
|
||||
+ acl_len = res.acl_len - res.acl_data_offset;
|
||||
+ if (acl_len > args.acl_len)
|
||||
+ nfs4_write_cached_acl(inode, NULL, acl_len);
|
||||
else
|
||||
- nfs4_write_cached_acl(inode, resp_buf, res.acl_len);
|
||||
+ nfs4_write_cached_acl(inode, resp_buf + res.acl_data_offset,
|
||||
+ acl_len);
|
||||
if (buf) {
|
||||
ret = -ERANGE;
|
||||
- if (res.acl_len > buflen)
|
||||
+ if (acl_len > buflen)
|
||||
goto out_free;
|
||||
- if (localpage)
|
||||
- memcpy(buf, resp_buf, res.acl_len);
|
||||
+ _copy_from_pages(buf, pages, res.acl_data_offset,
|
||||
+ res.acl_len);
|
||||
}
|
||||
- ret = res.acl_len;
|
||||
+ ret = acl_len;
|
||||
out_free:
|
||||
- if (localpage)
|
||||
- __free_page(localpage);
|
||||
+ for (i = 0; i < npages; i++)
|
||||
+ if (pages[i])
|
||||
+ __free_page(pages[i]);
|
||||
+ if (args.acl_scratch)
|
||||
+ __free_page(args.acl_scratch);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3621,6 +3637,8 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen)
|
||||
nfs_zap_acl_cache(inode);
|
||||
ret = nfs4_read_cached_acl(inode, buf, buflen);
|
||||
if (ret != -ENOENT)
|
||||
+ /* -ENOENT is returned if there is no ACL or if there is an ACL
|
||||
+ * but no cached acl data, just the acl length */
|
||||
return ret;
|
||||
return nfs4_get_acl_uncached(inode, buf, buflen);
|
||||
}
|
||||
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
|
||||
index e6161b2..dcaf693 100644
|
||||
--- a/fs/nfs/nfs4xdr.c
|
||||
+++ b/fs/nfs/nfs4xdr.c
|
||||
@@ -2517,11 +2517,13 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
|
||||
encode_compound_hdr(xdr, req, &hdr);
|
||||
encode_sequence(xdr, &args->seq_args, &hdr);
|
||||
encode_putfh(xdr, args->fh, &hdr);
|
||||
- replen = hdr.replen + op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz + 1;
|
||||
+ replen = hdr.replen + op_decode_hdr_maxsz + 1;
|
||||
encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr);
|
||||
|
||||
xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
|
||||
args->acl_pages, args->acl_pgbase, args->acl_len);
|
||||
+ xdr_set_scratch_buffer(xdr, page_address(args->acl_scratch), PAGE_SIZE);
|
||||
+
|
||||
encode_nops(&hdr);
|
||||
}
|
||||
|
||||
@@ -4957,17 +4959,18 @@ decode_restorefh(struct xdr_stream *xdr)
|
||||
}
|
||||
|
||||
static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
|
||||
- size_t *acl_len)
|
||||
+ struct nfs_getaclres *res)
|
||||
{
|
||||
- __be32 *savep;
|
||||
+ __be32 *savep, *bm_p;
|
||||
uint32_t attrlen,
|
||||
bitmap[3] = {0};
|
||||
struct kvec *iov = req->rq_rcv_buf.head;
|
||||
int status;
|
||||
|
||||
- *acl_len = 0;
|
||||
+ res->acl_len = 0;
|
||||
if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
|
||||
goto out;
|
||||
+ bm_p = xdr->p;
|
||||
if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
|
||||
goto out;
|
||||
if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
|
||||
@@ -4979,18 +4982,30 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
|
||||
size_t hdrlen;
|
||||
u32 recvd;
|
||||
|
||||
+ /* The bitmap (xdr len + bitmaps) and the attr xdr len words
|
||||
+ * are stored with the acl data to handle the problem of
|
||||
+ * variable length bitmaps.*/
|
||||
+ xdr->p = bm_p;
|
||||
+ res->acl_data_offset = be32_to_cpup(bm_p) + 2;
|
||||
+ res->acl_data_offset <<= 2;
|
||||
+
|
||||
/* We ignore &savep and don't do consistency checks on
|
||||
* the attr length. Let userspace figure it out.... */
|
||||
hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base;
|
||||
+ attrlen += res->acl_data_offset;
|
||||
recvd = req->rq_rcv_buf.len - hdrlen;
|
||||
if (attrlen > recvd) {
|
||||
- dprintk("NFS: server cheating in getattr"
|
||||
- " acl reply: attrlen %u > recvd %u\n",
|
||||
+ if (res->acl_flags & NFS4_ACL_LEN_REQUEST) {
|
||||
+ /* getxattr interface called with a NULL buf */
|
||||
+ res->acl_len = attrlen;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ dprintk("NFS: acl reply: attrlen %u > recvd %u\n",
|
||||
attrlen, recvd);
|
||||
return -EINVAL;
|
||||
}
|
||||
xdr_read_pages(xdr, attrlen);
|
||||
- *acl_len = attrlen;
|
||||
+ res->acl_len = attrlen;
|
||||
} else
|
||||
status = -EOPNOTSUPP;
|
||||
|
||||
@@ -6028,7 +6043,7 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
|
||||
status = decode_putfh(xdr);
|
||||
if (status)
|
||||
goto out;
|
||||
- status = decode_getacl(xdr, rqstp, &res->acl_len);
|
||||
+ status = decode_getacl(xdr, rqstp, res);
|
||||
|
||||
out:
|
||||
return status;
|
||||
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
|
||||
index 2a7c533..6c898af 100644
|
||||
--- a/include/linux/nfs_xdr.h
|
||||
+++ b/include/linux/nfs_xdr.h
|
||||
@@ -602,11 +602,16 @@ struct nfs_getaclargs {
|
||||
size_t acl_len;
|
||||
unsigned int acl_pgbase;
|
||||
struct page ** acl_pages;
|
||||
+ struct page * acl_scratch;
|
||||
struct nfs4_sequence_args seq_args;
|
||||
};
|
||||
|
||||
+/* getxattr ACL interface flags */
|
||||
+#define NFS4_ACL_LEN_REQUEST 0x0001 /* zero length getxattr buffer */
|
||||
struct nfs_getaclres {
|
||||
size_t acl_len;
|
||||
+ size_t acl_data_offset;
|
||||
+ int acl_flags;
|
||||
struct nfs4_sequence_res seq_res;
|
||||
};
|
||||
|
||||
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
|
||||
index a20970e..af70af3 100644
|
||||
--- a/include/linux/sunrpc/xdr.h
|
||||
+++ b/include/linux/sunrpc/xdr.h
|
||||
@@ -191,6 +191,8 @@ extern int xdr_decode_array2(struct xdr_buf *buf, unsigned int base,
|
||||
struct xdr_array2_desc *desc);
|
||||
extern int xdr_encode_array2(struct xdr_buf *buf, unsigned int base,
|
||||
struct xdr_array2_desc *desc);
|
||||
+extern void _copy_from_pages(char *p, struct page **pages, size_t pgbase,
|
||||
+ size_t len);
|
||||
|
||||
/*
|
||||
* Provide some simple tools for XDR buffer overflow-checking etc.
|
||||
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
|
||||
index 277ebd4..593f4c6 100644
|
||||
--- a/net/sunrpc/xdr.c
|
||||
+++ b/net/sunrpc/xdr.c
|
||||
@@ -296,7 +296,7 @@ _copy_to_pages(struct page **pages, size_t pgbase, const char *p, size_t len)
|
||||
* Copies data into an arbitrary memory location from an array of pages
|
||||
* The copy is assumed to be non-overlapping.
|
||||
*/
|
||||
-static void
|
||||
+void
|
||||
_copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len)
|
||||
{
|
||||
struct page **pgfrom;
|
||||
@@ -324,6 +324,7 @@ _copy_from_pages(char *p, struct page **pages, size_t pgbase, size_t len)
|
||||
|
||||
} while ((len -= copy) != 0);
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(_copy_from_pages);
|
||||
|
||||
/*
|
||||
* xdr_shrink_bufhead
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
From e7d23a1c02013b27699c8d993ef0ceb6e3110955 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff Layton <jlayton@redhat.com>
|
||||
Date: Tue, 20 Dec 2011 06:57:45 -0500
|
||||
Subject: [PATCH 026/130] nfs: fix regression in handling of context= option
|
||||
in NFSv4
|
||||
|
||||
commit 8a0d551a59ac92d8ff048d6cb29d3a02073e81e8 upstream.
|
||||
|
||||
Setting the security context of a NFSv4 mount via the context= mount
|
||||
option is currently broken. The NFSv4 codepath allocates a parsed
|
||||
options struct, and then parses the mount options to fill it. It
|
||||
eventually calls nfs4_remote_mount which calls security_init_mnt_opts.
|
||||
That clobbers the lsm_opts struct that was populated earlier. This bug
|
||||
also looks like it causes a small memory leak on each v4 mount where
|
||||
context= is used.
|
||||
|
||||
Fix this by moving the initialization of the lsm_opts into
|
||||
nfs_alloc_parsed_mount_data. Also, add a destructor for
|
||||
nfs_parsed_mount_data to make it easier to free all of the allocations
|
||||
hanging off of it, and to ensure that the security_free_mnt_opts is
|
||||
called whenever security_init_mnt_opts is.
|
||||
|
||||
I believe this regression was introduced quite some time ago, probably
|
||||
by commit c02d7adf.
|
||||
|
||||
Signed-off-by: Jeff Layton <jlayton@redhat.com>
|
||||
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
fs/nfs/super.c | 43 +++++++++++++++++++------------------------
|
||||
1 files changed, 19 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
|
||||
index 1347774..3ada13c 100644
|
||||
--- a/fs/nfs/super.c
|
||||
+++ b/fs/nfs/super.c
|
||||
@@ -909,10 +909,24 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int ve
|
||||
data->auth_flavor_len = 1;
|
||||
data->version = version;
|
||||
data->minorversion = 0;
|
||||
+ security_init_mnt_opts(&data->lsm_opts);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
+static void nfs_free_parsed_mount_data(struct nfs_parsed_mount_data *data)
|
||||
+{
|
||||
+ if (data) {
|
||||
+ kfree(data->client_address);
|
||||
+ kfree(data->mount_server.hostname);
|
||||
+ kfree(data->nfs_server.export_path);
|
||||
+ kfree(data->nfs_server.hostname);
|
||||
+ kfree(data->fscache_uniq);
|
||||
+ security_free_mnt_opts(&data->lsm_opts);
|
||||
+ kfree(data);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Sanity-check a server address provided by the mount command.
|
||||
*
|
||||
@@ -2220,9 +2234,7 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
|
||||
data = nfs_alloc_parsed_mount_data(NFS_DEFAULT_VERSION);
|
||||
mntfh = nfs_alloc_fhandle();
|
||||
if (data == NULL || mntfh == NULL)
|
||||
- goto out_free_fh;
|
||||
-
|
||||
- security_init_mnt_opts(&data->lsm_opts);
|
||||
+ goto out;
|
||||
|
||||
/* Validate the mount data */
|
||||
error = nfs_validate_mount_data(raw_data, data, mntfh, dev_name);
|
||||
@@ -2234,8 +2246,6 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
|
||||
#ifdef CONFIG_NFS_V4
|
||||
if (data->version == 4) {
|
||||
mntroot = nfs4_try_mount(flags, dev_name, data);
|
||||
- kfree(data->client_address);
|
||||
- kfree(data->nfs_server.export_path);
|
||||
goto out;
|
||||
}
|
||||
#endif /* CONFIG_NFS_V4 */
|
||||
@@ -2290,13 +2300,8 @@ static struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
|
||||
s->s_flags |= MS_ACTIVE;
|
||||
|
||||
out:
|
||||
- kfree(data->nfs_server.hostname);
|
||||
- kfree(data->mount_server.hostname);
|
||||
- kfree(data->fscache_uniq);
|
||||
- security_free_mnt_opts(&data->lsm_opts);
|
||||
-out_free_fh:
|
||||
+ nfs_free_parsed_mount_data(data);
|
||||
nfs_free_fhandle(mntfh);
|
||||
- kfree(data);
|
||||
return mntroot;
|
||||
|
||||
out_err_nosb:
|
||||
@@ -2623,9 +2628,7 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
|
||||
|
||||
mntfh = nfs_alloc_fhandle();
|
||||
if (data == NULL || mntfh == NULL)
|
||||
- goto out_free_fh;
|
||||
-
|
||||
- security_init_mnt_opts(&data->lsm_opts);
|
||||
+ goto out;
|
||||
|
||||
/* Get a volume representation */
|
||||
server = nfs4_create_server(data, mntfh);
|
||||
@@ -2677,13 +2680,10 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
|
||||
|
||||
s->s_flags |= MS_ACTIVE;
|
||||
|
||||
- security_free_mnt_opts(&data->lsm_opts);
|
||||
nfs_free_fhandle(mntfh);
|
||||
return mntroot;
|
||||
|
||||
out:
|
||||
- security_free_mnt_opts(&data->lsm_opts);
|
||||
-out_free_fh:
|
||||
nfs_free_fhandle(mntfh);
|
||||
return ERR_PTR(error);
|
||||
|
||||
@@ -2838,7 +2838,7 @@ static struct dentry *nfs4_mount(struct file_system_type *fs_type,
|
||||
|
||||
data = nfs_alloc_parsed_mount_data(4);
|
||||
if (data == NULL)
|
||||
- goto out_free_data;
|
||||
+ goto out;
|
||||
|
||||
/* Validate the mount data */
|
||||
error = nfs4_validate_mount_data(raw_data, data, dev_name);
|
||||
@@ -2852,12 +2852,7 @@ static struct dentry *nfs4_mount(struct file_system_type *fs_type,
|
||||
error = PTR_ERR(res);
|
||||
|
||||
out:
|
||||
- kfree(data->client_address);
|
||||
- kfree(data->nfs_server.export_path);
|
||||
- kfree(data->nfs_server.hostname);
|
||||
- kfree(data->fscache_uniq);
|
||||
-out_free_data:
|
||||
- kfree(data);
|
||||
+ nfs_free_parsed_mount_data(data);
|
||||
dprintk("<-- nfs4_mount() = %d%s\n", error,
|
||||
error != 0 ? " [error]" : "");
|
||||
return res;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
From 1d30ef7aee8f11c3f90038ba7d57a82e0acbadb5 Mon Sep 17 00:00:00 2001
|
||||
From: Chase Douglas <chase.douglas@canonical.com>
|
||||
Date: Mon, 7 Nov 2011 11:08:05 -0800
|
||||
Subject: [PATCH 027/130] HID: bump maximum global item tag report size to 96
|
||||
bytes
|
||||
|
||||
commit e46e927b9b7e8d95526e69322855243882b7e1a3 upstream.
|
||||
|
||||
This allows the latest N-Trig devices to function properly.
|
||||
|
||||
BugLink: https://bugs.launchpad.net/bugs/724831
|
||||
|
||||
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
|
||||
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/hid/hid-core.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
|
||||
index af35384..1473067 100644
|
||||
--- a/drivers/hid/hid-core.c
|
||||
+++ b/drivers/hid/hid-core.c
|
||||
@@ -362,7 +362,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
|
||||
|
||||
case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
|
||||
parser->global.report_size = item_udata(item);
|
||||
- if (parser->global.report_size > 32) {
|
||||
+ if (parser->global.report_size > 96) {
|
||||
dbg_hid("invalid report_size %d\n",
|
||||
parser->global.report_size);
|
||||
return -1;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
From f60dd210e7edd913a760ca4c4f9df2c6341f5ef8 Mon Sep 17 00:00:00 2001
|
||||
From: David Herrmann <dh.herrmann@googlemail.com>
|
||||
Date: Wed, 7 Dec 2011 21:33:59 +0100
|
||||
Subject: [PATCH 028/130] HID: wiimote: Select INPUT_FF_MEMLESS
|
||||
|
||||
commit ef6f41157f3864d9bf42671b2ed66062dcafb72e upstream.
|
||||
|
||||
We depend on memless force-feedback support, therefore correctly select the
|
||||
related config options.
|
||||
|
||||
Reported-by: Randy Dunlap <rdunlap@xenotime.net>
|
||||
Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
|
||||
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/hid/Kconfig | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
|
||||
index 22a4a05..332c22a 100644
|
||||
--- a/drivers/hid/Kconfig
|
||||
+++ b/drivers/hid/Kconfig
|
||||
@@ -620,6 +620,7 @@ config HID_WIIMOTE
|
||||
depends on BT_HIDP
|
||||
depends on LEDS_CLASS
|
||||
select POWER_SUPPLY
|
||||
+ select INPUT_FF_MEMLESS
|
||||
---help---
|
||||
Support for the Nintendo Wii Remote bluetooth device.
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
From e20542f497522671fa121d7612442a2557bfa2ff Mon Sep 17 00:00:00 2001
|
||||
From: Bhavesh Parekh <bparekh@nvidia.com>
|
||||
Date: Wed, 30 Nov 2011 17:43:42 +0530
|
||||
Subject: [PATCH 029/130] UBI: fix missing scrub when there is a bit-flip
|
||||
|
||||
commit e801e128b2200c40a0ec236cf2330b2586b6e05a upstream.
|
||||
|
||||
Under some cases, when scrubbing the PEB if we did not get the lock on
|
||||
the PEB it fails to scrub. Add that PEB again to the scrub list
|
||||
|
||||
Artem: minor amendments.
|
||||
|
||||
Signed-off-by: Bhavesh Parekh <bparekh@nvidia.com>
|
||||
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/mtd/ubi/eba.c | 6 ++++--
|
||||
drivers/mtd/ubi/ubi.h | 2 ++
|
||||
drivers/mtd/ubi/wl.c | 5 ++++-
|
||||
3 files changed, 10 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
|
||||
index fb7f19b..cd26da8 100644
|
||||
--- a/drivers/mtd/ubi/eba.c
|
||||
+++ b/drivers/mtd/ubi/eba.c
|
||||
@@ -1028,12 +1028,14 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
|
||||
* 'ubi_wl_put_peb()' function on the @ubi->move_mutex. In turn, we are
|
||||
* holding @ubi->move_mutex and go sleep on the LEB lock. So, if the
|
||||
* LEB is already locked, we just do not move it and return
|
||||
- * %MOVE_CANCEL_RACE, which means that UBI will re-try, but later.
|
||||
+ * %MOVE_RETRY. Note, we do not return %MOVE_CANCEL_RACE here because
|
||||
+ * we do not know the reasons of the contention - it may be just a
|
||||
+ * normal I/O on this LEB, so we want to re-try.
|
||||
*/
|
||||
err = leb_write_trylock(ubi, vol_id, lnum);
|
||||
if (err) {
|
||||
dbg_wl("contention on LEB %d:%d, cancel", vol_id, lnum);
|
||||
- return MOVE_CANCEL_RACE;
|
||||
+ return MOVE_RETRY;
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
|
||||
index dc64c76..d51d75d 100644
|
||||
--- a/drivers/mtd/ubi/ubi.h
|
||||
+++ b/drivers/mtd/ubi/ubi.h
|
||||
@@ -120,6 +120,7 @@ enum {
|
||||
* PEB
|
||||
* MOVE_CANCEL_BITFLIPS: canceled because a bit-flip was detected in the
|
||||
* target PEB
|
||||
+ * MOVE_RETRY: retry scrubbing the PEB
|
||||
*/
|
||||
enum {
|
||||
MOVE_CANCEL_RACE = 1,
|
||||
@@ -127,6 +128,7 @@ enum {
|
||||
MOVE_TARGET_RD_ERR,
|
||||
MOVE_TARGET_WR_ERR,
|
||||
MOVE_CANCEL_BITFLIPS,
|
||||
+ MOVE_RETRY,
|
||||
};
|
||||
|
||||
/**
|
||||
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
|
||||
index 42c684c..277c429 100644
|
||||
--- a/drivers/mtd/ubi/wl.c
|
||||
+++ b/drivers/mtd/ubi/wl.c
|
||||
@@ -795,7 +795,10 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
|
||||
protect = 1;
|
||||
goto out_not_moved;
|
||||
}
|
||||
-
|
||||
+ if (err == MOVE_RETRY) {
|
||||
+ scrubbing = 1;
|
||||
+ goto out_not_moved;
|
||||
+ }
|
||||
if (err == MOVE_CANCEL_BITFLIPS || err == MOVE_TARGET_WR_ERR ||
|
||||
err == MOVE_TARGET_RD_ERR) {
|
||||
/*
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
From e9089302a9d795113e8efe652fe30331d75d1fd8 Mon Sep 17 00:00:00 2001
|
||||
From: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
|
||||
Date: Thu, 5 Jan 2012 10:47:18 +0200
|
||||
Subject: [PATCH 030/130] UBI: fix use-after-free on error path
|
||||
|
||||
commit e57e0d8e818512047fe379157c3f77f1b9fabffb upstream.
|
||||
|
||||
When we fail to erase a PEB, we free the corresponding erase entry object,
|
||||
but then re-schedule this object if the error code was something like -EAGAIN.
|
||||
Obviously, it is a bug to use the object after we have freed it.
|
||||
|
||||
Reported-by: Emese Revfy <re.emese@gmail.com>
|
||||
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/mtd/ubi/wl.c | 7 ++++---
|
||||
1 files changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
|
||||
index 277c429..0696e36 100644
|
||||
--- a/drivers/mtd/ubi/wl.c
|
||||
+++ b/drivers/mtd/ubi/wl.c
|
||||
@@ -1052,7 +1052,6 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
|
||||
|
||||
ubi_err("failed to erase PEB %d, error %d", pnum, err);
|
||||
kfree(wl_wrk);
|
||||
- kmem_cache_free(ubi_wl_entry_slab, e);
|
||||
|
||||
if (err == -EINTR || err == -ENOMEM || err == -EAGAIN ||
|
||||
err == -EBUSY) {
|
||||
@@ -1065,14 +1064,16 @@ static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
|
||||
goto out_ro;
|
||||
}
|
||||
return err;
|
||||
- } else if (err != -EIO) {
|
||||
+ }
|
||||
+
|
||||
+ kmem_cache_free(ubi_wl_entry_slab, e);
|
||||
+ if (err != -EIO)
|
||||
/*
|
||||
* If this is not %-EIO, we have no idea what to do. Scheduling
|
||||
* this physical eraseblock for erasure again would cause
|
||||
* errors again and again. Well, lets switch to R/O mode.
|
||||
*/
|
||||
goto out_ro;
|
||||
- }
|
||||
|
||||
/* It is %-EIO, the PEB went bad */
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
From 9d9e1e743ab7ca6f40a0f6f60f5ebda2a6b8b07b Mon Sep 17 00:00:00 2001
|
||||
From: Alex Williamson <alex.williamson@redhat.com>
|
||||
Date: Wed, 16 Nov 2011 09:24:16 -0700
|
||||
Subject: [PATCH 031/130] PCI: Fix PCI_EXP_TYPE_RC_EC value
|
||||
|
||||
commit 1830ea91c20b06608f7cdb2455ce05ba834b3214 upstream.
|
||||
|
||||
Spec shows this as 1010b = 0xa
|
||||
|
||||
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
|
||||
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
include/linux/pci_regs.h | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
|
||||
index b5d9657..411c412 100644
|
||||
--- a/include/linux/pci_regs.h
|
||||
+++ b/include/linux/pci_regs.h
|
||||
@@ -392,7 +392,7 @@
|
||||
#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */
|
||||
#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */
|
||||
#define PCI_EXP_TYPE_RC_END 0x9 /* Root Complex Integrated Endpoint */
|
||||
-#define PCI_EXP_TYPE_RC_EC 0x10 /* Root Complex Event Collector */
|
||||
+#define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */
|
||||
#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */
|
||||
#define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */
|
||||
#define PCI_EXP_DEVCAP 4 /* Device capabilities */
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
From 63365de9ebb1b944d0306668f726ad62a08a0371 Mon Sep 17 00:00:00 2001
|
||||
From: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
Date: Mon, 17 Oct 2011 11:46:06 -0700
|
||||
Subject: [PATCH 032/130] PCI: msi: Disable msi interrupts when we initialize
|
||||
a pci device
|
||||
|
||||
commit a776c491ca5e38c26d9f66923ff574d041e747f4 upstream.
|
||||
|
||||
I traced a nasty kexec on panic boot failure to the fact that we had
|
||||
screaming msi interrupts and we were not disabling the msi messages at
|
||||
kernel startup. The booting kernel had not enabled those interupts so
|
||||
was not prepared to handle them.
|
||||
|
||||
I can see no reason why we would ever want to leave the msi interrupts
|
||||
enabled at boot if something else has enabled those interrupts. The pci
|
||||
spec specifies that msi interrupts should be off by default. Drivers
|
||||
are expected to enable the msi interrupts if they want to use them. Our
|
||||
interrupt handling code reprograms the interrupt handlers at boot and
|
||||
will not be be able to do anything useful with an unexpected interrupt.
|
||||
|
||||
This patch applies cleanly all of the way back to 2.6.32 where I noticed
|
||||
the problem.
|
||||
|
||||
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
|
||||
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/pci/msi.c | 10 ++++++++++
|
||||
1 files changed, 10 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
|
||||
index 0e6d04d..e3efb43 100644
|
||||
--- a/drivers/pci/msi.c
|
||||
+++ b/drivers/pci/msi.c
|
||||
@@ -870,5 +870,15 @@ EXPORT_SYMBOL(pci_msi_enabled);
|
||||
|
||||
void pci_msi_init_pci_dev(struct pci_dev *dev)
|
||||
{
|
||||
+ int pos;
|
||||
INIT_LIST_HEAD(&dev->msi_list);
|
||||
+
|
||||
+ /* Disable the msi hardware to avoid screaming interrupts
|
||||
+ * during boot. This is the power on reset default so
|
||||
+ * usually this should be a noop.
|
||||
+ */
|
||||
+ pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
|
||||
+ if (pos)
|
||||
+ msi_set_enable(dev, pos, 0);
|
||||
+ msix_set_enable(dev, 0);
|
||||
}
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
From 5040b50e89f45f17231e6d2ad101596bedc5e431 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Hade <garyhade@us.ibm.com>
|
||||
Date: Mon, 14 Nov 2011 15:42:16 -0800
|
||||
Subject: [PATCH 033/130] x86/PCI: Ignore CPU non-addressable _CRS reserved
|
||||
memory resources
|
||||
|
||||
commit ae5cd86455381282ece162966183d3f208c6fad7 upstream.
|
||||
|
||||
This assures that a _CRS reserved host bridge window or window region is
|
||||
not used if it is not addressable by the CPU. The new code either trims
|
||||
the window to exclude the non-addressable portion or totally ignores the
|
||||
window if the entire window is non-addressable.
|
||||
|
||||
The current code has been shown to be problematic with 32-bit non-PAE
|
||||
kernels on systems where _CRS reserves resources above 4GB.
|
||||
|
||||
Signed-off-by: Gary Hade <garyhade@us.ibm.com>
|
||||
Reviewed-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||
Cc: Thomas Renninger <trenn@novell.com>
|
||||
Cc: linux-kernel@vger.kernel.org
|
||||
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
arch/x86/pci/acpi.c | 18 ++++++++++++++++--
|
||||
1 files changed, 16 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
|
||||
index 404f21a..f8348ab 100644
|
||||
--- a/arch/x86/pci/acpi.c
|
||||
+++ b/arch/x86/pci/acpi.c
|
||||
@@ -149,7 +149,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
|
||||
struct acpi_resource_address64 addr;
|
||||
acpi_status status;
|
||||
unsigned long flags;
|
||||
- u64 start, end;
|
||||
+ u64 start, orig_end, end;
|
||||
|
||||
status = resource_to_addr(acpi_res, &addr);
|
||||
if (!ACPI_SUCCESS(status))
|
||||
@@ -165,7 +165,21 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
|
||||
return AE_OK;
|
||||
|
||||
start = addr.minimum + addr.translation_offset;
|
||||
- end = addr.maximum + addr.translation_offset;
|
||||
+ orig_end = end = addr.maximum + addr.translation_offset;
|
||||
+
|
||||
+ /* Exclude non-addressable range or non-addressable portion of range */
|
||||
+ end = min(end, (u64)iomem_resource.end);
|
||||
+ if (end <= start) {
|
||||
+ dev_info(&info->bridge->dev,
|
||||
+ "host bridge window [%#llx-%#llx] "
|
||||
+ "(ignored, not CPU addressable)\n", start, orig_end);
|
||||
+ return AE_OK;
|
||||
+ } else if (orig_end != end) {
|
||||
+ dev_info(&info->bridge->dev,
|
||||
+ "host bridge window [%#llx-%#llx] "
|
||||
+ "([%#llx-%#llx] ignored, not CPU addressable)\n",
|
||||
+ start, orig_end, end + 1, orig_end);
|
||||
+ }
|
||||
|
||||
res = &info->res[info->res_num];
|
||||
res->name = info->name;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
From c6f611b87ae8cf8a5bd1fc916b4b63e0fd48d6f3 Mon Sep 17 00:00:00 2001
|
||||
From: Bjorn Helgaas <bhelgaas@google.com>
|
||||
Date: Thu, 5 Jan 2012 14:27:19 -0700
|
||||
Subject: [PATCH 034/130] x86/PCI: amd: factor out MMCONFIG discovery
|
||||
|
||||
commit 24d25dbfa63c376323096660bfa9ad45a08870ce upstream.
|
||||
|
||||
This factors out the AMD native MMCONFIG discovery so we can use it
|
||||
outside amd_bus.c.
|
||||
|
||||
amd_bus.c reads AMD MSRs so it can remove the MMCONFIG area from the
|
||||
PCI resources. We may also need the MMCONFIG information to work
|
||||
around BIOS defects in the ACPI MCFG table.
|
||||
|
||||
Cc: Borislav Petkov <borislav.petkov@amd.com>
|
||||
Cc: Yinghai Lu <yinghai@kernel.org>
|
||||
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
arch/x86/include/asm/amd_nb.h | 2 +
|
||||
arch/x86/kernel/amd_nb.c | 31 ++++++++++++++++++++++++++++++
|
||||
arch/x86/pci/amd_bus.c | 42 ++++++++++------------------------------
|
||||
3 files changed, 44 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h
|
||||
index 8e41071..49ad773 100644
|
||||
--- a/arch/x86/include/asm/amd_nb.h
|
||||
+++ b/arch/x86/include/asm/amd_nb.h
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef _ASM_X86_AMD_NB_H
|
||||
#define _ASM_X86_AMD_NB_H
|
||||
|
||||
+#include <linux/ioport.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
struct amd_nb_bus_dev_range {
|
||||
@@ -13,6 +14,7 @@ extern const struct pci_device_id amd_nb_misc_ids[];
|
||||
extern const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[];
|
||||
|
||||
extern bool early_is_amd_nb(u32 value);
|
||||
+extern struct resource *amd_get_mmconfig_range(struct resource *res);
|
||||
extern int amd_cache_northbridges(void);
|
||||
extern void amd_flush_garts(void);
|
||||
extern int amd_numa_init(void);
|
||||
diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
|
||||
index 4c39baa..bae1efe 100644
|
||||
--- a/arch/x86/kernel/amd_nb.c
|
||||
+++ b/arch/x86/kernel/amd_nb.c
|
||||
@@ -119,6 +119,37 @@ bool __init early_is_amd_nb(u32 device)
|
||||
return false;
|
||||
}
|
||||
|
||||
+struct resource *amd_get_mmconfig_range(struct resource *res)
|
||||
+{
|
||||
+ u32 address;
|
||||
+ u64 base, msr;
|
||||
+ unsigned segn_busn_bits;
|
||||
+
|
||||
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
|
||||
+ return NULL;
|
||||
+
|
||||
+ /* assume all cpus from fam10h have mmconfig */
|
||||
+ if (boot_cpu_data.x86 < 0x10)
|
||||
+ return NULL;
|
||||
+
|
||||
+ address = MSR_FAM10H_MMIO_CONF_BASE;
|
||||
+ rdmsrl(address, msr);
|
||||
+
|
||||
+ /* mmconfig is not enabled */
|
||||
+ if (!(msr & FAM10H_MMIO_CONF_ENABLE))
|
||||
+ return NULL;
|
||||
+
|
||||
+ base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
|
||||
+
|
||||
+ segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
|
||||
+ FAM10H_MMIO_CONF_BUSRANGE_MASK;
|
||||
+
|
||||
+ res->flags = IORESOURCE_MEM;
|
||||
+ res->start = base;
|
||||
+ res->end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
int amd_get_subcaches(int cpu)
|
||||
{
|
||||
struct pci_dev *link = node_to_amd_nb(amd_get_nb_id(cpu))->link;
|
||||
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
|
||||
index 026e493..385a940 100644
|
||||
--- a/arch/x86/pci/amd_bus.c
|
||||
+++ b/arch/x86/pci/amd_bus.c
|
||||
@@ -30,34 +30,6 @@ static struct pci_hostbridge_probe pci_probes[] __initdata = {
|
||||
{ 0, 0x18, PCI_VENDOR_ID_AMD, 0x1300 },
|
||||
};
|
||||
|
||||
-static u64 __initdata fam10h_mmconf_start;
|
||||
-static u64 __initdata fam10h_mmconf_end;
|
||||
-static void __init get_pci_mmcfg_amd_fam10h_range(void)
|
||||
-{
|
||||
- u32 address;
|
||||
- u64 base, msr;
|
||||
- unsigned segn_busn_bits;
|
||||
-
|
||||
- /* assume all cpus from fam10h have mmconf */
|
||||
- if (boot_cpu_data.x86 < 0x10)
|
||||
- return;
|
||||
-
|
||||
- address = MSR_FAM10H_MMIO_CONF_BASE;
|
||||
- rdmsrl(address, msr);
|
||||
-
|
||||
- /* mmconfig is not enable */
|
||||
- if (!(msr & FAM10H_MMIO_CONF_ENABLE))
|
||||
- return;
|
||||
-
|
||||
- base = msr & (FAM10H_MMIO_CONF_BASE_MASK<<FAM10H_MMIO_CONF_BASE_SHIFT);
|
||||
-
|
||||
- segn_busn_bits = (msr >> FAM10H_MMIO_CONF_BUSRANGE_SHIFT) &
|
||||
- FAM10H_MMIO_CONF_BUSRANGE_MASK;
|
||||
-
|
||||
- fam10h_mmconf_start = base;
|
||||
- fam10h_mmconf_end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
|
||||
-}
|
||||
-
|
||||
#define RANGE_NUM 16
|
||||
|
||||
/**
|
||||
@@ -85,6 +57,9 @@ static int __init early_fill_mp_bus_info(void)
|
||||
u64 val;
|
||||
u32 address;
|
||||
bool found;
|
||||
+ struct resource fam10h_mmconf_res, *fam10h_mmconf;
|
||||
+ u64 fam10h_mmconf_start;
|
||||
+ u64 fam10h_mmconf_end;
|
||||
|
||||
if (!early_pci_allowed())
|
||||
return -1;
|
||||
@@ -211,12 +186,17 @@ static int __init early_fill_mp_bus_info(void)
|
||||
subtract_range(range, RANGE_NUM, 0, end);
|
||||
|
||||
/* get mmconfig */
|
||||
- get_pci_mmcfg_amd_fam10h_range();
|
||||
+ fam10h_mmconf = amd_get_mmconfig_range(&fam10h_mmconf_res);
|
||||
/* need to take out mmconf range */
|
||||
- if (fam10h_mmconf_end) {
|
||||
- printk(KERN_DEBUG "Fam 10h mmconf [%llx, %llx]\n", fam10h_mmconf_start, fam10h_mmconf_end);
|
||||
+ if (fam10h_mmconf) {
|
||||
+ printk(KERN_DEBUG "Fam 10h mmconf %pR\n", fam10h_mmconf);
|
||||
+ fam10h_mmconf_start = fam10h_mmconf->start;
|
||||
+ fam10h_mmconf_end = fam10h_mmconf->end;
|
||||
subtract_range(range, RANGE_NUM, fam10h_mmconf_start,
|
||||
fam10h_mmconf_end + 1);
|
||||
+ } else {
|
||||
+ fam10h_mmconf_start = 0;
|
||||
+ fam10h_mmconf_end = 0;
|
||||
}
|
||||
|
||||
/* mmio resource */
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
From a67bd4738894215f045d9d1aed024277cb5ae99e Mon Sep 17 00:00:00 2001
|
||||
From: Bjorn Helgaas <bhelgaas@google.com>
|
||||
Date: Thu, 12 Jan 2012 08:01:40 -0700
|
||||
Subject: [PATCH 035/130] x86/PCI: build amd_bus.o only when CONFIG_AMD_NB=y
|
||||
|
||||
commit 5cf9a4e69c1ff0ccdd1d2b7404f95c0531355274 upstream.
|
||||
|
||||
We only need amd_bus.o for AMD systems with PCI. arch/x86/pci/Makefile
|
||||
already depends on CONFIG_PCI=y, so this patch just adds the dependency
|
||||
on CONFIG_AMD_NB.
|
||||
|
||||
Cc: Yinghai Lu <yinghai@kernel.org>
|
||||
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
arch/x86/pci/Makefile | 3 ++-
|
||||
1 files changed, 2 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
|
||||
index 6b8759f..d24d3da 100644
|
||||
--- a/arch/x86/pci/Makefile
|
||||
+++ b/arch/x86/pci/Makefile
|
||||
@@ -18,8 +18,9 @@ obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
|
||||
obj-$(CONFIG_X86_MRST) += mrst.o
|
||||
|
||||
obj-y += common.o early.o
|
||||
-obj-y += amd_bus.o bus_numa.o
|
||||
+obj-y += bus_numa.o
|
||||
|
||||
+obj-$(CONFIG_AMD_NB) += amd_bus.o
|
||||
obj-$(CONFIG_PCI_CNB20LE_QUIRK) += broadcom_bus.o
|
||||
|
||||
ifeq ($(CONFIG_PCI_DEBUG),y)
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
From c96f90776325ceb9fcda278cba8bc85e287d8d15 Mon Sep 17 00:00:00 2001
|
||||
From: "nagalakshmi.nandigama@lsi.com" <nagalakshmi.nandigama@lsi.com>
|
||||
Date: Thu, 1 Dec 2011 07:52:56 +0530
|
||||
Subject: [PATCH 036/130] SCSI: mpt2sas: Release spinlock for the raid device
|
||||
list before blocking it
|
||||
|
||||
commit 30c43282f3d347f47f9e05199d2b14f56f3f2837 upstream.
|
||||
|
||||
Added code to release the spinlock that is used to protect the
|
||||
raid device list before calling a function that can block. The
|
||||
blocking was causing a reschedule, and subsequently it is tried
|
||||
to acquire the same lock, resulting in a panic (NMI Watchdog
|
||||
detecting a CPU lockup).
|
||||
|
||||
Signed-off-by: Nagalakshmi Nandigama <nagalakshmi.nandigama@lsi.com>
|
||||
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/scsi/mpt2sas/mpt2sas_scsih.c | 7 ++++---
|
||||
1 files changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
|
||||
index d570573..3a4f666 100644
|
||||
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
|
||||
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
|
||||
@@ -6714,6 +6714,7 @@ _scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid,
|
||||
} else
|
||||
sas_target_priv_data = NULL;
|
||||
raid_device->responding = 1;
|
||||
+ spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
|
||||
starget_printk(KERN_INFO, raid_device->starget,
|
||||
"handle(0x%04x), wwid(0x%016llx)\n", handle,
|
||||
(unsigned long long)raid_device->wwid);
|
||||
@@ -6724,16 +6725,16 @@ _scsih_mark_responding_raid_device(struct MPT2SAS_ADAPTER *ioc, u64 wwid,
|
||||
*/
|
||||
_scsih_init_warpdrive_properties(ioc, raid_device);
|
||||
if (raid_device->handle == handle)
|
||||
- goto out;
|
||||
+ return;
|
||||
printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
|
||||
raid_device->handle);
|
||||
raid_device->handle = handle;
|
||||
if (sas_target_priv_data)
|
||||
sas_target_priv_data->handle = handle;
|
||||
- goto out;
|
||||
+ return;
|
||||
}
|
||||
}
|
||||
- out:
|
||||
+
|
||||
spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
|
||||
}
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+177
@@ -0,0 +1,177 @@
|
||||
From fe5907648567469336c06cf215932adac76a8e11 Mon Sep 17 00:00:00 2001
|
||||
From: "nagalakshmi.nandigama@lsi.com" <nagalakshmi.nandigama@lsi.com>
|
||||
Date: Thu, 1 Dec 2011 07:53:08 +0530
|
||||
Subject: [PATCH 037/130] SCSI: mpt2sas : Fix for memory allocation error for
|
||||
large host credits
|
||||
|
||||
commit aff132d95ffe14eca96cab90597cdd010b457af7 upstream.
|
||||
|
||||
The amount of memory required for tracking chain buffers is rather
|
||||
large, and when the host credit count is big, memory allocation
|
||||
failure occurs inside __get_free_pages.
|
||||
|
||||
The fix is to limit the number of chains to 100,000. In addition,
|
||||
the number of host credits is limited to 30,000 IOs. However this
|
||||
limitation can be overridden this using the command line option
|
||||
max_queue_depth. The algorithm for calculating the
|
||||
reply_post_queue_depth is changed so that it is equal to
|
||||
(reply_free_queue_depth + 16), previously it was (reply_free_queue_depth * 2).
|
||||
|
||||
Signed-off-by: Nagalakshmi Nandigama <nagalakshmi.nandigama@lsi.com>
|
||||
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/scsi/mpt2sas/mpt2sas_base.c | 83 +++++++++++-----------------------
|
||||
drivers/scsi/mpt2sas/mpt2sas_scsih.c | 4 +-
|
||||
2 files changed, 29 insertions(+), 58 deletions(-)
|
||||
|
||||
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
|
||||
index beda04a..0794c72 100644
|
||||
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
|
||||
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
|
||||
@@ -65,6 +65,8 @@ static MPT_CALLBACK mpt_callbacks[MPT_MAX_CALLBACKS];
|
||||
|
||||
#define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */
|
||||
|
||||
+#define MAX_HBA_QUEUE_DEPTH 30000
|
||||
+#define MAX_CHAIN_DEPTH 100000
|
||||
static int max_queue_depth = -1;
|
||||
module_param(max_queue_depth, int, 0);
|
||||
MODULE_PARM_DESC(max_queue_depth, " max controller queue depth ");
|
||||
@@ -2311,8 +2313,6 @@ _base_release_memory_pools(struct MPT2SAS_ADAPTER *ioc)
|
||||
}
|
||||
if (ioc->chain_dma_pool)
|
||||
pci_pool_destroy(ioc->chain_dma_pool);
|
||||
- }
|
||||
- if (ioc->chain_lookup) {
|
||||
free_pages((ulong)ioc->chain_lookup, ioc->chain_pages);
|
||||
ioc->chain_lookup = NULL;
|
||||
}
|
||||
@@ -2330,9 +2330,7 @@ static int
|
||||
_base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
|
||||
{
|
||||
struct mpt2sas_facts *facts;
|
||||
- u32 queue_size, queue_diff;
|
||||
u16 max_sge_elements;
|
||||
- u16 num_of_reply_frames;
|
||||
u16 chains_needed_per_io;
|
||||
u32 sz, total_sz, reply_post_free_sz;
|
||||
u32 retry_sz;
|
||||
@@ -2359,7 +2357,8 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
|
||||
max_request_credit = (max_queue_depth < facts->RequestCredit)
|
||||
? max_queue_depth : facts->RequestCredit;
|
||||
else
|
||||
- max_request_credit = facts->RequestCredit;
|
||||
+ max_request_credit = min_t(u16, facts->RequestCredit,
|
||||
+ MAX_HBA_QUEUE_DEPTH);
|
||||
|
||||
ioc->hba_queue_depth = max_request_credit;
|
||||
ioc->hi_priority_depth = facts->HighPriorityCredit;
|
||||
@@ -2400,50 +2399,25 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
|
||||
}
|
||||
ioc->chains_needed_per_io = chains_needed_per_io;
|
||||
|
||||
- /* reply free queue sizing - taking into account for events */
|
||||
- num_of_reply_frames = ioc->hba_queue_depth + 32;
|
||||
-
|
||||
- /* number of replies frames can't be a multiple of 16 */
|
||||
- /* decrease number of reply frames by 1 */
|
||||
- if (!(num_of_reply_frames % 16))
|
||||
- num_of_reply_frames--;
|
||||
-
|
||||
- /* calculate number of reply free queue entries
|
||||
- * (must be multiple of 16)
|
||||
- */
|
||||
-
|
||||
- /* (we know reply_free_queue_depth is not a multiple of 16) */
|
||||
- queue_size = num_of_reply_frames;
|
||||
- queue_size += 16 - (queue_size % 16);
|
||||
- ioc->reply_free_queue_depth = queue_size;
|
||||
-
|
||||
- /* reply descriptor post queue sizing */
|
||||
- /* this size should be the number of request frames + number of reply
|
||||
- * frames
|
||||
- */
|
||||
-
|
||||
- queue_size = ioc->hba_queue_depth + num_of_reply_frames + 1;
|
||||
- /* round up to 16 byte boundary */
|
||||
- if (queue_size % 16)
|
||||
- queue_size += 16 - (queue_size % 16);
|
||||
-
|
||||
- /* check against IOC maximum reply post queue depth */
|
||||
- if (queue_size > facts->MaxReplyDescriptorPostQueueDepth) {
|
||||
- queue_diff = queue_size -
|
||||
- facts->MaxReplyDescriptorPostQueueDepth;
|
||||
+ /* reply free queue sizing - taking into account for 64 FW events */
|
||||
+ ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64;
|
||||
|
||||
- /* round queue_diff up to multiple of 16 */
|
||||
- if (queue_diff % 16)
|
||||
- queue_diff += 16 - (queue_diff % 16);
|
||||
-
|
||||
- /* adjust hba_queue_depth, reply_free_queue_depth,
|
||||
- * and queue_size
|
||||
- */
|
||||
- ioc->hba_queue_depth -= (queue_diff / 2);
|
||||
- ioc->reply_free_queue_depth -= (queue_diff / 2);
|
||||
- queue_size = facts->MaxReplyDescriptorPostQueueDepth;
|
||||
+ /* align the reply post queue on the next 16 count boundary */
|
||||
+ if (!ioc->reply_free_queue_depth % 16)
|
||||
+ ioc->reply_post_queue_depth = ioc->reply_free_queue_depth + 16;
|
||||
+ else
|
||||
+ ioc->reply_post_queue_depth = ioc->reply_free_queue_depth +
|
||||
+ 32 - (ioc->reply_free_queue_depth % 16);
|
||||
+ if (ioc->reply_post_queue_depth >
|
||||
+ facts->MaxReplyDescriptorPostQueueDepth) {
|
||||
+ ioc->reply_post_queue_depth = min_t(u16,
|
||||
+ (facts->MaxReplyDescriptorPostQueueDepth -
|
||||
+ (facts->MaxReplyDescriptorPostQueueDepth % 16)),
|
||||
+ (ioc->hba_queue_depth - (ioc->hba_queue_depth % 16)));
|
||||
+ ioc->reply_free_queue_depth = ioc->reply_post_queue_depth - 16;
|
||||
+ ioc->hba_queue_depth = ioc->reply_free_queue_depth - 64;
|
||||
}
|
||||
- ioc->reply_post_queue_depth = queue_size;
|
||||
+
|
||||
|
||||
dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scatter gather: "
|
||||
"sge_in_main_msg(%d), sge_per_chain(%d), sge_per_io(%d), "
|
||||
@@ -2529,15 +2503,12 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
|
||||
"depth(%d)\n", ioc->name, ioc->request,
|
||||
ioc->scsiio_depth));
|
||||
|
||||
- /* loop till the allocation succeeds */
|
||||
- do {
|
||||
- sz = ioc->chain_depth * sizeof(struct chain_tracker);
|
||||
- ioc->chain_pages = get_order(sz);
|
||||
- ioc->chain_lookup = (struct chain_tracker *)__get_free_pages(
|
||||
- GFP_KERNEL, ioc->chain_pages);
|
||||
- if (ioc->chain_lookup == NULL)
|
||||
- ioc->chain_depth -= 100;
|
||||
- } while (ioc->chain_lookup == NULL);
|
||||
+ ioc->chain_depth = min_t(u32, ioc->chain_depth, MAX_CHAIN_DEPTH);
|
||||
+ sz = ioc->chain_depth * sizeof(struct chain_tracker);
|
||||
+ ioc->chain_pages = get_order(sz);
|
||||
+
|
||||
+ ioc->chain_lookup = (struct chain_tracker *)__get_free_pages(
|
||||
+ GFP_KERNEL, ioc->chain_pages);
|
||||
ioc->chain_dma_pool = pci_pool_create("chain pool", ioc->pdev,
|
||||
ioc->request_sz, 16, 0);
|
||||
if (!ioc->chain_dma_pool) {
|
||||
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
|
||||
index 3a4f666..9bc6fb2 100644
|
||||
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
|
||||
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
|
||||
@@ -1007,8 +1007,8 @@ _scsih_get_chain_buffer_tracker(struct MPT2SAS_ADAPTER *ioc, u16 smid)
|
||||
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
|
||||
if (list_empty(&ioc->free_chain_list)) {
|
||||
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
|
||||
- printk(MPT2SAS_WARN_FMT "chain buffers not available\n",
|
||||
- ioc->name);
|
||||
+ dfailprintk(ioc, printk(MPT2SAS_WARN_FMT "chain buffers not "
|
||||
+ "available\n", ioc->name));
|
||||
return NULL;
|
||||
}
|
||||
chain_req = list_entry(ioc->free_chain_list.next,
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
From fbefcde91f27d0a80ebe70c0b3359b2e6c463cc0 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Campbell <Ian.Campbell@citrix.com>
|
||||
Date: Wed, 4 Jan 2012 09:34:49 +0000
|
||||
Subject: [PATCH 038/130] xen/xenbus: Reject replies with payload >
|
||||
XENSTORE_PAYLOAD_MAX.
|
||||
|
||||
commit 9e7860cee18241633eddb36a4c34c7b61d8cecbc upstream.
|
||||
|
||||
Haogang Chen found out that:
|
||||
|
||||
There is a potential integer overflow in process_msg() that could result
|
||||
in cross-domain attack.
|
||||
|
||||
body = kmalloc(msg->hdr.len + 1, GFP_NOIO | __GFP_HIGH);
|
||||
|
||||
When a malicious guest passes 0xffffffff in msg->hdr.len, the subsequent
|
||||
call to xb_read() would write to a zero-length buffer.
|
||||
|
||||
The other end of this connection is always the xenstore backend daemon
|
||||
so there is no guest (malicious or otherwise) which can do this. The
|
||||
xenstore daemon is a trusted component in the system.
|
||||
|
||||
However this seem like a reasonable robustness improvement so we should
|
||||
have it.
|
||||
|
||||
And Ian when read the API docs found that:
|
||||
The payload length (len field of the header) is limited to 4096
|
||||
(XENSTORE_PAYLOAD_MAX) in both directions. If a client exceeds the
|
||||
limit, its xenstored connection will be immediately killed by
|
||||
xenstored, which is usually catastrophic from the client's point of
|
||||
view. Clients (particularly domains, which cannot just reconnect)
|
||||
should avoid this.
|
||||
|
||||
so this patch checks against that instead.
|
||||
|
||||
This also avoids a potential integer overflow pointed out by Haogang Chen.
|
||||
|
||||
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
|
||||
Cc: Haogang Chen <haogangchen@gmail.com>
|
||||
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/xen/xenbus/xenbus_xs.c | 6 ++++++
|
||||
include/xen/interface/io/xs_wire.h | 3 +++
|
||||
2 files changed, 9 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c
|
||||
index ede860f..a580b17 100644
|
||||
--- a/drivers/xen/xenbus/xenbus_xs.c
|
||||
+++ b/drivers/xen/xenbus/xenbus_xs.c
|
||||
@@ -801,6 +801,12 @@ static int process_msg(void)
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ if (msg->hdr.len > XENSTORE_PAYLOAD_MAX) {
|
||||
+ kfree(msg);
|
||||
+ err = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
body = kmalloc(msg->hdr.len + 1, GFP_NOIO | __GFP_HIGH);
|
||||
if (body == NULL) {
|
||||
kfree(msg);
|
||||
diff --git a/include/xen/interface/io/xs_wire.h b/include/xen/interface/io/xs_wire.h
|
||||
index f6f07aa..7cdfca2 100644
|
||||
--- a/include/xen/interface/io/xs_wire.h
|
||||
+++ b/include/xen/interface/io/xs_wire.h
|
||||
@@ -87,4 +87,7 @@ struct xenstore_domain_interface {
|
||||
XENSTORE_RING_IDX rsp_cons, rsp_prod;
|
||||
};
|
||||
|
||||
+/* Violating this is very bad. See docs/misc/xenstore.txt. */
|
||||
+#define XENSTORE_PAYLOAD_MAX 4096
|
||||
+
|
||||
#endif /* _XS_WIRE_H */
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
From b08c639fb415855bbca91bff089b8bada0f4b044 Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Mon, 9 Jan 2012 01:41:51 +1100
|
||||
Subject: [PATCH 039/130] md/raid1: perform bad-block tests for WriteMostly
|
||||
devices too.
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
commit 307729c8bc5b5a41361af8af95906eee7552acb1 upstream.
|
||||
|
||||
We normally try to avoid reading from write-mostly devices, but when
|
||||
we do we really have to check for bad blocks and be sure not to
|
||||
try reading them.
|
||||
|
||||
With the current code, best_good_sectors might not get set and that
|
||||
causes zero-length read requests to be send down which is very
|
||||
confusing.
|
||||
|
||||
This bug was introduced in commit d2eb35acfdccbe2 and so the patch
|
||||
is suitable for 3.1.x and 3.2.x
|
||||
|
||||
Reported-and-tested-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
|
||||
Reported-and-tested-by: Art -kwaak- van Breemen <ard@telegraafnet.nl>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/md/raid1.c | 11 ++++++++++-
|
||||
1 files changed, 10 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
|
||||
index ede2461..7d9e071 100644
|
||||
--- a/drivers/md/raid1.c
|
||||
+++ b/drivers/md/raid1.c
|
||||
@@ -525,8 +525,17 @@ static int read_balance(struct r1conf *conf, struct r1bio *r1_bio, int *max_sect
|
||||
if (test_bit(WriteMostly, &rdev->flags)) {
|
||||
/* Don't balance among write-mostly, just
|
||||
* use the first as a last resort */
|
||||
- if (best_disk < 0)
|
||||
+ if (best_disk < 0) {
|
||||
+ if (is_badblock(rdev, this_sector, sectors,
|
||||
+ &first_bad, &bad_sectors)) {
|
||||
+ if (first_bad < this_sector)
|
||||
+ /* Cannot use this */
|
||||
+ continue;
|
||||
+ best_good_sectors = first_bad - this_sector;
|
||||
+ } else
|
||||
+ best_good_sectors = sectors;
|
||||
best_disk = disk;
|
||||
+ }
|
||||
continue;
|
||||
}
|
||||
/* This is a reasonable device to use. It might
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
From 52e6ae83dbb962de0a33d2cd1b610cdfd0a09b0d Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Sassu <roberto.sassu@polito.it>
|
||||
Date: Mon, 19 Dec 2011 15:57:27 +0100
|
||||
Subject: [PATCH 040/130] ima: free duplicate measurement memory
|
||||
|
||||
commit 45fae7493970d7c45626ccd96d4a74f5f1eea5a9 upstream.
|
||||
|
||||
Info about new measurements are cached in the iint for performance. When
|
||||
the inode is flushed from cache, the associated iint is flushed as well.
|
||||
Subsequent access to the inode will cause the inode to be re-measured and
|
||||
will attempt to add a duplicate entry to the measurement list.
|
||||
|
||||
This patch frees the duplicate measurement memory, fixing a memory leak.
|
||||
|
||||
Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
|
||||
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
security/integrity/ima/ima_api.c | 4 ++--
|
||||
security/integrity/ima/ima_queue.c | 1 +
|
||||
2 files changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
|
||||
index 0d50df0..88a2788 100644
|
||||
--- a/security/integrity/ima/ima_api.c
|
||||
+++ b/security/integrity/ima/ima_api.c
|
||||
@@ -178,8 +178,8 @@ void ima_store_measurement(struct integrity_iint_cache *iint,
|
||||
strncpy(entry->template.file_name, filename, IMA_EVENT_NAME_LEN_MAX);
|
||||
|
||||
result = ima_store_template(entry, violation, inode);
|
||||
- if (!result)
|
||||
+ if (!result || result == -EEXIST)
|
||||
iint->flags |= IMA_MEASURED;
|
||||
- else
|
||||
+ if (result < 0)
|
||||
kfree(entry);
|
||||
}
|
||||
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
|
||||
index 8e28f04..e1a5062 100644
|
||||
--- a/security/integrity/ima/ima_queue.c
|
||||
+++ b/security/integrity/ima/ima_queue.c
|
||||
@@ -114,6 +114,7 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
|
||||
memcpy(digest, entry->digest, sizeof digest);
|
||||
if (ima_lookup_digest_entry(digest)) {
|
||||
audit_cause = "hash_exists";
|
||||
+ result = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
From b5be4dc54cfe7c5bb0ce387519c2019d9915435e Mon Sep 17 00:00:00 2001
|
||||
From: Roberto Sassu <roberto.sassu@polito.it>
|
||||
Date: Mon, 19 Dec 2011 15:57:28 +0100
|
||||
Subject: [PATCH 041/130] ima: fix invalid memory reference
|
||||
|
||||
commit 7b7e5916aa2f46e57f8bd8cb89c34620ebfda5da upstream.
|
||||
|
||||
Don't free a valid measurement entry on TPM PCR extend failure.
|
||||
|
||||
Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
|
||||
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
security/integrity/ima/ima_queue.c | 16 +++++++++++-----
|
||||
1 files changed, 11 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
|
||||
index e1a5062..55a6271 100644
|
||||
--- a/security/integrity/ima/ima_queue.c
|
||||
+++ b/security/integrity/ima/ima_queue.c
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <linux/slab.h>
|
||||
#include "ima.h"
|
||||
|
||||
+#define AUDIT_CAUSE_LEN_MAX 32
|
||||
+
|
||||
LIST_HEAD(ima_measurements); /* list of all measurements */
|
||||
|
||||
/* key: inode (before secure-hashing a file) */
|
||||
@@ -94,7 +96,8 @@ static int ima_pcr_extend(const u8 *hash)
|
||||
|
||||
result = tpm_pcr_extend(TPM_ANY_NUM, CONFIG_IMA_MEASURE_PCR_IDX, hash);
|
||||
if (result != 0)
|
||||
- pr_err("IMA: Error Communicating to TPM chip\n");
|
||||
+ pr_err("IMA: Error Communicating to TPM chip, result: %d\n",
|
||||
+ result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -106,8 +109,9 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
|
||||
{
|
||||
u8 digest[IMA_DIGEST_SIZE];
|
||||
const char *audit_cause = "hash_added";
|
||||
+ char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX];
|
||||
int audit_info = 1;
|
||||
- int result = 0;
|
||||
+ int result = 0, tpmresult = 0;
|
||||
|
||||
mutex_lock(&ima_extend_list_mutex);
|
||||
if (!violation) {
|
||||
@@ -129,9 +133,11 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
|
||||
if (violation) /* invalidate pcr */
|
||||
memset(digest, 0xff, sizeof digest);
|
||||
|
||||
- result = ima_pcr_extend(digest);
|
||||
- if (result != 0) {
|
||||
- audit_cause = "TPM error";
|
||||
+ tpmresult = ima_pcr_extend(digest);
|
||||
+ if (tpmresult != 0) {
|
||||
+ snprintf(tpm_audit_cause, AUDIT_CAUSE_LEN_MAX, "TPM_error(%d)",
|
||||
+ tpmresult);
|
||||
+ audit_cause = tpm_audit_cause;
|
||||
audit_info = 0;
|
||||
}
|
||||
out:
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
From c25b1c3dffca9191001f97e64c9be8e1ff861c0a Mon Sep 17 00:00:00 2001
|
||||
From: Eric Dumazet <eric.dumazet@gmail.com>
|
||||
Date: Tue, 13 Dec 2011 04:57:06 +0100
|
||||
Subject: [PATCH 042/130] slub: fix a possible memleak in __slab_alloc()
|
||||
|
||||
commit 73736e0387ba0e6d2b703407b4d26168d31516a7 upstream.
|
||||
|
||||
Zhihua Che reported a possible memleak in slub allocator on
|
||||
CONFIG_PREEMPT=y builds.
|
||||
|
||||
It is possible current thread migrates right before disabling irqs in
|
||||
__slab_alloc(). We must check again c->freelist, and perform a normal
|
||||
allocation instead of scratching c->freelist.
|
||||
|
||||
Many thanks to Zhihua Che for spotting this bug, introduced in 2.6.39
|
||||
|
||||
V2: Its also possible an IRQ freed one (or several) object(s) and
|
||||
populated c->freelist, so its not a CONFIG_PREEMPT only problem.
|
||||
|
||||
Reported-by: Zhihua Che <zhihua.che@gmail.com>
|
||||
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
|
||||
Acked-by: Christoph Lameter <cl@linux.com>
|
||||
Signed-off-by: Pekka Enberg <penberg@kernel.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
mm/slub.c | 5 +++++
|
||||
1 files changed, 5 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/mm/slub.c b/mm/slub.c
|
||||
index ed3334d..1a919f0 100644
|
||||
--- a/mm/slub.c
|
||||
+++ b/mm/slub.c
|
||||
@@ -2166,6 +2166,11 @@ redo:
|
||||
goto new_slab;
|
||||
}
|
||||
|
||||
+ /* must check again c->freelist in case of cpu migration or IRQ */
|
||||
+ object = c->freelist;
|
||||
+ if (object)
|
||||
+ goto load_freelist;
|
||||
+
|
||||
stat(s, ALLOC_SLOWPATH);
|
||||
|
||||
do {
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
From c450bfbe6e0d5b7feb3c7570c2f22c4a8da7ca44 Mon Sep 17 00:00:00 2001
|
||||
From: Bjorn Helgaas <bhelgaas@google.com>
|
||||
Date: Thu, 5 Jan 2012 14:27:24 -0700
|
||||
Subject: [PATCH 043/130] PNP: work around Dell 1536/1546 BIOS MMCONFIG bug
|
||||
that breaks USB
|
||||
|
||||
commit eb31aae8cb5eb54e234ed2d857ddac868195d911 upstream.
|
||||
|
||||
Some Dell BIOSes have MCFG tables that don't report the entire
|
||||
MMCONFIG area claimed by the chipset. If we move PCI devices into
|
||||
that claimed-but-unreported area, they don't work.
|
||||
|
||||
This quirk reads the AMD MMCONFIG MSRs and adds PNP0C01 resources as
|
||||
needed to cover the entire area.
|
||||
|
||||
Example problem scenario:
|
||||
|
||||
BIOS-e820: 00000000cfec5400 - 00000000d4000000 (reserved)
|
||||
Fam 10h mmconf [d0000000, dfffffff]
|
||||
PCI: MMCONFIG for domain 0000 [bus 00-3f] at [mem 0xd0000000-0xd3ffffff] (base 0xd0000000)
|
||||
pnp 00:0c: [mem 0xd0000000-0xd3ffffff]
|
||||
pci 0000:00:12.0: reg 10: [mem 0xffb00000-0xffb00fff]
|
||||
pci 0000:00:12.0: no compatible bridge window for [mem 0xffb00000-0xffb00fff]
|
||||
pci 0000:00:12.0: BAR 0: assigned [mem 0xd4000000-0xd40000ff]
|
||||
|
||||
Reported-by: Lisa Salimbas <lisa.salimbas@canonical.com>
|
||||
Reported-by: <thuban@singularity.fr>
|
||||
Tested-by: dann frazier <dann.frazier@canonical.com>
|
||||
References: https://bugzilla.kernel.org/show_bug.cgi?id=31602
|
||||
References: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/647043
|
||||
References: https://bugzilla.redhat.com/show_bug.cgi?id=770308
|
||||
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
||||
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/pnp/quirks.c | 42 ++++++++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 42 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
|
||||
index dfbd5a6..258fef2 100644
|
||||
--- a/drivers/pnp/quirks.c
|
||||
+++ b/drivers/pnp/quirks.c
|
||||
@@ -295,6 +295,45 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
|
||||
}
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_AMD_NB
|
||||
+
|
||||
+#include <asm/amd_nb.h>
|
||||
+
|
||||
+static void quirk_amd_mmconfig_area(struct pnp_dev *dev)
|
||||
+{
|
||||
+ resource_size_t start, end;
|
||||
+ struct pnp_resource *pnp_res;
|
||||
+ struct resource *res;
|
||||
+ struct resource mmconfig_res, *mmconfig;
|
||||
+
|
||||
+ mmconfig = amd_get_mmconfig_range(&mmconfig_res);
|
||||
+ if (!mmconfig)
|
||||
+ return;
|
||||
+
|
||||
+ list_for_each_entry(pnp_res, &dev->resources, list) {
|
||||
+ res = &pnp_res->res;
|
||||
+ if (res->end < mmconfig->start || res->start > mmconfig->end ||
|
||||
+ (res->start == mmconfig->start && res->end == mmconfig->end))
|
||||
+ continue;
|
||||
+
|
||||
+ dev_info(&dev->dev, FW_BUG
|
||||
+ "%pR covers only part of AMD MMCONFIG area %pR; adding more reservations\n",
|
||||
+ res, mmconfig);
|
||||
+ if (mmconfig->start < res->start) {
|
||||
+ start = mmconfig->start;
|
||||
+ end = res->start - 1;
|
||||
+ pnp_add_mem_resource(dev, start, end, 0);
|
||||
+ }
|
||||
+ if (mmconfig->end > res->end) {
|
||||
+ start = res->end + 1;
|
||||
+ end = mmconfig->end;
|
||||
+ pnp_add_mem_resource(dev, start, end, 0);
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* PnP Quirks
|
||||
* Cards or devices that need some tweaking due to incomplete resource info
|
||||
@@ -322,6 +361,9 @@ static struct pnp_fixup pnp_fixups[] = {
|
||||
/* PnP resources that might overlap PCI BARs */
|
||||
{"PNP0c01", quirk_system_pci_resources},
|
||||
{"PNP0c02", quirk_system_pci_resources},
|
||||
+#ifdef CONFIG_AMD_NB
|
||||
+ {"PNP0c01", quirk_amd_mmconfig_area},
|
||||
+#endif
|
||||
{""}
|
||||
};
|
||||
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
From 95bb58957d5f4db07339eb5c6c87345ec877a3b6 Mon Sep 17 00:00:00 2001
|
||||
From: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
|
||||
Date: Tue, 10 Jan 2012 06:40:23 +0000
|
||||
Subject: [PATCH 044/130] asix: fix setting custom MAC address on Asix 88178
|
||||
devices
|
||||
|
||||
commit 71bc5d94061516c4e70303570128797bcf768b10 upstream.
|
||||
|
||||
In kernel v3.2 initialization sequence for Asix 88178 devices was changed so
|
||||
that hardware is reseted on every time interface is brought up (ifconfig up),
|
||||
instead just at USB probe time. This causes problem with setting custom MAC
|
||||
address to device as ax88178_reset causes reload of MAC address from EEPROM.
|
||||
|
||||
This patch fixes the issue by rewriting MAC address at end of ax88178_reset.
|
||||
|
||||
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
|
||||
Acked-by: Grant Grundler <grundler@chromium.org>
|
||||
Cc: Allan Chou <allan@asix.com.tw>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/net/usb/asix.c | 7 +++++++
|
||||
1 files changed, 7 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
|
||||
index dd2625a..b495821 100644
|
||||
--- a/drivers/net/usb/asix.c
|
||||
+++ b/drivers/net/usb/asix.c
|
||||
@@ -1316,6 +1316,13 @@ static int ax88178_reset(struct usbnet *dev)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
+ /* Rewrite MAC address */
|
||||
+ memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN);
|
||||
+ ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN,
|
||||
+ data->mac_addr);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
From 25a43c8a8f51501928b5d209ab3880ecd5b180fe Mon Sep 17 00:00:00 2001
|
||||
From: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
|
||||
Date: Tue, 10 Jan 2012 06:40:17 +0000
|
||||
Subject: [PATCH 045/130] asix: fix setting custom MAC address on Asix 88772
|
||||
devices
|
||||
|
||||
commit 8ef66bdc4bda6aac2dae73b84d79dc8c2db33637 upstream.
|
||||
|
||||
In kernel v3.2 initialization sequence for Asix 88772 devices was changed so
|
||||
that hardware is reseted on every time interface is brought up (ifconfig up),
|
||||
instead just at USB probe time. This causes problem with setting custom MAC
|
||||
address to device as ax88772_reset causes reload of MAC address from EEPROM.
|
||||
|
||||
This patch fixes the issue by rewriting MAC address at end of ax88772_reset.
|
||||
|
||||
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
|
||||
Acked-by: Grant Grundler <grundler@chromium.org>
|
||||
Cc: Allan Chou <allan@asix.com.tw>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/net/usb/asix.c | 8 ++++++++
|
||||
1 files changed, 8 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c
|
||||
index b495821..f5e063a 100644
|
||||
--- a/drivers/net/usb/asix.c
|
||||
+++ b/drivers/net/usb/asix.c
|
||||
@@ -974,6 +974,7 @@ static int ax88772_link_reset(struct usbnet *dev)
|
||||
|
||||
static int ax88772_reset(struct usbnet *dev)
|
||||
{
|
||||
+ struct asix_data *data = (struct asix_data *)&dev->data;
|
||||
int ret, embd_phy;
|
||||
u16 rx_ctl;
|
||||
|
||||
@@ -1051,6 +1052,13 @@ static int ax88772_reset(struct usbnet *dev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ /* Rewrite MAC address */
|
||||
+ memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN);
|
||||
+ ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN,
|
||||
+ data->mac_addr);
|
||||
+ if (ret < 0)
|
||||
+ goto out;
|
||||
+
|
||||
/* Set RX_CTL to default values with 2k buffer, and enable cactus */
|
||||
ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL);
|
||||
if (ret < 0)
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
From 56d30a3ff947d9e4be88a6083eb257bffb7d059e Mon Sep 17 00:00:00 2001
|
||||
From: Fabio Estevam <festevam@gmail.com>
|
||||
Date: Thu, 12 Jan 2012 17:20:20 -0800
|
||||
Subject: [PATCH 046/130] include/linux/crash_dump.h needs elf.h
|
||||
|
||||
commit 1f536b9e9f85456df93614b3c2f6a1a2b7d7cb9b upstream.
|
||||
|
||||
Building an ARM target we get the following warnings:
|
||||
|
||||
CC arch/arm/kernel/setup.o
|
||||
In file included from arch/arm/kernel/setup.c:39:
|
||||
arch/arm/include/asm/elf.h:102:1: warning: "vmcore_elf64_check_arch" redefined
|
||||
In file included from arch/arm/kernel/setup.c:24:
|
||||
include/linux/crash_dump.h:30:1: warning: this is the location of the previous definition
|
||||
|
||||
Quoting Russell King:
|
||||
|
||||
"linux/crash_dump.h makes no attempt to include asm/elf.h, but it depends
|
||||
on stuff in asm/elf.h to determine how stuff inside this file is defined
|
||||
at parse time.
|
||||
|
||||
So, if asm/elf.h is included after linux/crash_dump.h or not at all, you
|
||||
get a different result from the situation where asm/elf.h is included
|
||||
before."
|
||||
|
||||
So add elf.h header to crash_dump.h to avoid this problem.
|
||||
|
||||
The original discussion about this can be found at:
|
||||
http://www.spinics.net/lists/arm-kernel/msg154113.html
|
||||
|
||||
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
|
||||
Cc: Russell King <rmk@arm.linux.org.uk>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
include/linux/crash_dump.h | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
|
||||
index 5c4abce..b936763 100644
|
||||
--- a/include/linux/crash_dump.h
|
||||
+++ b/include/linux/crash_dump.h
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/proc_fs.h>
|
||||
+#include <linux/elf.h>
|
||||
|
||||
#define ELFCORE_ADDR_MAX (-1ULL)
|
||||
#define ELFCORE_ADDR_ERR (-2ULL)
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
From 5b48b119d0d1a2331b6368b4be7e3c1406cbda40 Mon Sep 17 00:00:00 2001
|
||||
From: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Date: Wed, 4 Jan 2012 20:50:47 -0600
|
||||
Subject: [PATCH 047/130] rtl8192se: Fix BUG caused by failure to check skb
|
||||
allocation
|
||||
|
||||
commit d90db4b12bc1b9b8a787ef28550fdb767ee25a49 upstream.
|
||||
|
||||
When downloading firmware into the device, the driver fails to check the
|
||||
return when allocating an skb. When the allocation fails, a BUG can be
|
||||
generated, as seen in https://bugzilla.redhat.com/show_bug.cgi?id=771656.
|
||||
|
||||
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
|
||||
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/net/wireless/rtlwifi/rtl8192se/fw.c | 4 ++++
|
||||
1 files changed, 4 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
|
||||
index 6f91a14..3fda6b1 100644
|
||||
--- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
|
||||
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
|
||||
@@ -196,6 +196,8 @@ static bool _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw,
|
||||
/* Allocate skb buffer to contain firmware */
|
||||
/* info and tx descriptor info. */
|
||||
skb = dev_alloc_skb(frag_length);
|
||||
+ if (!skb)
|
||||
+ return false;
|
||||
skb_reserve(skb, extra_descoffset);
|
||||
seg_ptr = (u8 *)skb_put(skb, (u32)(frag_length -
|
||||
extra_descoffset));
|
||||
@@ -573,6 +575,8 @@ static bool _rtl92s_firmware_set_h2c_cmd(struct ieee80211_hw *hw, u8 h2c_cmd,
|
||||
|
||||
len = _rtl92s_get_h2c_cmdlen(MAX_TRANSMIT_BUFFER_SIZE, 1, &cmd_len);
|
||||
skb = dev_alloc_skb(len);
|
||||
+ if (!skb)
|
||||
+ return false;
|
||||
cb_desc = (struct rtl_tcb_desc *)(skb->cb);
|
||||
cb_desc->queue_index = TXCMD_QUEUE;
|
||||
cb_desc->cmd_or_init = DESC_PACKET_TYPE_NORMAL;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
From 70f755e08b2df34528ff568bcbe2b856ddd769e1 Mon Sep 17 00:00:00 2001
|
||||
From: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Date: Wed, 11 Jan 2012 09:26:54 +0100
|
||||
Subject: [PATCH 048/130] mac80211: fix rx->key NULL pointer dereference in
|
||||
promiscuous mode
|
||||
|
||||
commit 1140afa862842ac3e56678693050760edc4ecde9 upstream.
|
||||
|
||||
Since:
|
||||
|
||||
commit 816c04fe7ef01dd9649f5ccfe796474db8708be5
|
||||
Author: Christian Lamparter <chunkeey@googlemail.com>
|
||||
Date: Sat Apr 30 15:24:30 2011 +0200
|
||||
|
||||
mac80211: consolidate MIC failure report handling
|
||||
|
||||
is possible to that we dereference rx->key == NULL when driver set
|
||||
RX_FLAG_MMIC_STRIPPED and not RX_FLAG_IV_STRIPPED and we are in
|
||||
promiscuous mode. This happen with rt73usb and rt61pci at least.
|
||||
|
||||
Before the commit we always check rx->key against NULL, so I assume
|
||||
fix should be done in mac80211 (also mic_fail path has similar check).
|
||||
|
||||
References:
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=769766
|
||||
http://rt2x00.serialmonkey.com/pipermail/users_rt2x00.serialmonkey.com/2012-January/004395.html
|
||||
|
||||
Reported-by: Stuart D Gathman <stuart@gathman.org>
|
||||
Reported-by: Kai Wohlfahrt <kai.scorpio@gmail.com>
|
||||
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
net/mac80211/wpa.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
|
||||
index f614ce7..28a39bb 100644
|
||||
--- a/net/mac80211/wpa.c
|
||||
+++ b/net/mac80211/wpa.c
|
||||
@@ -106,7 +106,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
|
||||
if (status->flag & RX_FLAG_MMIC_ERROR)
|
||||
goto mic_fail;
|
||||
|
||||
- if (!(status->flag & RX_FLAG_IV_STRIPPED))
|
||||
+ if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key)
|
||||
goto update_iv;
|
||||
|
||||
return RX_CONTINUE;
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
From 11da5d38bc749c576b8def78827c2ca82d6d6bb6 Mon Sep 17 00:00:00 2001
|
||||
From: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
|
||||
Date: Mon, 9 Jan 2012 15:37:53 +0530
|
||||
Subject: [PATCH 049/130] ath9k: Fix regression in channelwidth switch at the
|
||||
same channel
|
||||
|
||||
commit 1a19f77f3642b8194ad9cf55548cc5d92e841766 upstream.
|
||||
|
||||
The commit "ath9k: Fix invalid noisefloor reading due to channel update"
|
||||
preserves the current channel noisefloor readings before updating
|
||||
channel type at the same channel index. It is also updating the curchan
|
||||
pointer. As survey updation is also referring curchan pointer to fetch
|
||||
the appropriate index, which might leads to invalid memory access. This
|
||||
patch partially reverts the change and stores the noise floor history
|
||||
buffer before updating channel type w/o updating curchan.
|
||||
|
||||
Cc: Gary Morain <gmorain@google.com>
|
||||
Cc: Paul Stewart <pstew@google.com>
|
||||
Reported-by: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
|
||||
Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
|
||||
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
drivers/net/wireless/ath/ath9k/calib.c | 1 +
|
||||
drivers/net/wireless/ath/ath9k/main.c | 8 ++------
|
||||
2 files changed, 3 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
|
||||
index 9953881..8ddef3e 100644
|
||||
--- a/drivers/net/wireless/ath/ath9k/calib.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/calib.c
|
||||
@@ -402,6 +402,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
ah->noise = ath9k_hw_getchan_noise(ah, chan);
|
||||
return true;
|
||||
}
|
||||
+EXPORT_SYMBOL(ath9k_hw_getnf);
|
||||
|
||||
void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
|
||||
index a9c5ae7..f76a814 100644
|
||||
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||
@@ -1667,7 +1667,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
|
||||
struct ieee80211_channel *curchan = hw->conf.channel;
|
||||
- struct ath9k_channel old_chan;
|
||||
int pos = curchan->hw_value;
|
||||
int old_pos = -1;
|
||||
unsigned long flags;
|
||||
@@ -1693,11 +1692,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
|
||||
* Preserve the current channel values, before updating
|
||||
* the same channel
|
||||
*/
|
||||
- if (old_pos == pos) {
|
||||
- memcpy(&old_chan, &sc->sc_ah->channels[pos],
|
||||
- sizeof(struct ath9k_channel));
|
||||
- ah->curchan = &old_chan;
|
||||
- }
|
||||
+ if (ah->curchan && (old_pos == pos))
|
||||
+ ath9k_hw_getnf(ah, ah->curchan);
|
||||
|
||||
ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
|
||||
curchan, conf->channel_type);
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
+179
@@ -0,0 +1,179 @@
|
||||
From 256d142444317960a68e5c5e7a8b41a520b62bd9 Mon Sep 17 00:00:00 2001
|
||||
From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
|
||||
Date: Thu, 12 Jan 2012 17:17:44 -0800
|
||||
Subject: [PATCH 050/130] memcg: add mem_cgroup_replace_page_cache() to fix
|
||||
LRU issue
|
||||
|
||||
commit ab936cbcd02072a34b60d268f94440fd5cf1970b upstream.
|
||||
|
||||
Commit ef6a3c6311 ("mm: add replace_page_cache_page() function") added a
|
||||
function replace_page_cache_page(). This function replaces a page in the
|
||||
radix-tree with a new page. WHen doing this, memory cgroup needs to fix
|
||||
up the accounting information. memcg need to check PCG_USED bit etc.
|
||||
|
||||
In some(many?) cases, 'newpage' is on LRU before calling
|
||||
replace_page_cache(). So, memcg's LRU accounting information should be
|
||||
fixed, too.
|
||||
|
||||
This patch adds mem_cgroup_replace_page_cache() and removes the old hooks.
|
||||
In that function, old pages will be unaccounted without touching
|
||||
res_counter and new page will be accounted to the memcg (of old page).
|
||||
WHen overwriting pc->mem_cgroup of newpage, take zone->lru_lock and avoid
|
||||
races with LRU handling.
|
||||
|
||||
Background:
|
||||
replace_page_cache_page() is called by FUSE code in its splice() handling.
|
||||
Here, 'newpage' is replacing oldpage but this newpage is not a newly allocated
|
||||
page and may be on LRU. LRU mis-accounting will be critical for memory cgroup
|
||||
because rmdir() checks the whole LRU is empty and there is no account leak.
|
||||
If a page is on the other LRU than it should be, rmdir() will fail.
|
||||
|
||||
This bug was added in March 2011, but no bug report yet. I guess there
|
||||
are not many people who use memcg and FUSE at the same time with upstream
|
||||
kernels.
|
||||
|
||||
The result of this bug is that admin cannot destroy a memcg because of
|
||||
account leak. So, no panic, no deadlock. And, even if an active cgroup
|
||||
exist, umount can succseed. So no problem at shutdown.
|
||||
|
||||
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
|
||||
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
|
||||
Acked-by: Michal Hocko <mhocko@suse.cz>
|
||||
Cc: Miklos Szeredi <mszeredi@suse.cz>
|
||||
Cc: Hugh Dickins <hughd@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
---
|
||||
include/linux/memcontrol.h | 6 ++++++
|
||||
mm/filemap.c | 18 ++----------------
|
||||
mm/memcontrol.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 52 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
|
||||
index b87068a..81572af 100644
|
||||
--- a/include/linux/memcontrol.h
|
||||
+++ b/include/linux/memcontrol.h
|
||||
@@ -119,6 +119,8 @@ struct zone_reclaim_stat*
|
||||
mem_cgroup_get_reclaim_stat_from_page(struct page *page);
|
||||
extern void mem_cgroup_print_oom_info(struct mem_cgroup *memcg,
|
||||
struct task_struct *p);
|
||||
+extern void mem_cgroup_replace_page_cache(struct page *oldpage,
|
||||
+ struct page *newpage);
|
||||
|
||||
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP
|
||||
extern int do_swap_account;
|
||||
@@ -366,6 +368,10 @@ static inline
|
||||
void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx)
|
||||
{
|
||||
}
|
||||
+static inline void mem_cgroup_replace_page_cache(struct page *oldpage,
|
||||
+ struct page *newpage)
|
||||
+{
|
||||
+}
|
||||
#endif /* CONFIG_CGROUP_MEM_CONT */
|
||||
|
||||
#if !defined(CONFIG_CGROUP_MEM_RES_CTLR) || !defined(CONFIG_DEBUG_VM)
|
||||
diff --git a/mm/filemap.c b/mm/filemap.c
|
||||
index 5f0a3c9..90286a4 100644
|
||||
--- a/mm/filemap.c
|
||||
+++ b/mm/filemap.c
|
||||
@@ -393,24 +393,11 @@ EXPORT_SYMBOL(filemap_write_and_wait_range);
|
||||
int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask)
|
||||
{
|
||||
int error;
|
||||
- struct mem_cgroup *memcg = NULL;
|
||||
|
||||
VM_BUG_ON(!PageLocked(old));
|
||||
VM_BUG_ON(!PageLocked(new));
|
||||
VM_BUG_ON(new->mapping);
|
||||
|
||||
- /*
|
||||
- * This is not page migration, but prepare_migration and
|
||||
- * end_migration does enough work for charge replacement.
|
||||
- *
|
||||
- * In the longer term we probably want a specialized function
|
||||
- * for moving the charge from old to new in a more efficient
|
||||
- * manner.
|
||||
- */
|
||||
- error = mem_cgroup_prepare_migration(old, new, &memcg, gfp_mask);
|
||||
- if (error)
|
||||
- return error;
|
||||
-
|
||||
error = radix_tree_preload(gfp_mask & ~__GFP_HIGHMEM);
|
||||
if (!error) {
|
||||
struct address_space *mapping = old->mapping;
|
||||
@@ -432,13 +419,12 @@ int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask)
|
||||
if (PageSwapBacked(new))
|
||||
__inc_zone_page_state(new, NR_SHMEM);
|
||||
spin_unlock_irq(&mapping->tree_lock);
|
||||
+ /* mem_cgroup codes must not be called under tree_lock */
|
||||
+ mem_cgroup_replace_page_cache(old, new);
|
||||
radix_tree_preload_end();
|
||||
if (freepage)
|
||||
freepage(old);
|
||||
page_cache_release(old);
|
||||
- mem_cgroup_end_migration(memcg, old, new, true);
|
||||
- } else {
|
||||
- mem_cgroup_end_migration(memcg, old, new, false);
|
||||
}
|
||||
|
||||
return error;
|
||||
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
|
||||
index b63f5f7..f538e9b 100644
|
||||
--- a/mm/memcontrol.c
|
||||
+++ b/mm/memcontrol.c
|
||||
@@ -3366,6 +3366,50 @@ void mem_cgroup_end_migration(struct mem_cgroup *memcg,
|
||||
cgroup_release_and_wakeup_rmdir(&memcg->css);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * At replace page cache, newpage is not under any memcg but it's on
|
||||
+ * LRU. So, this function doesn't touch res_counter but handles LRU
|
||||
+ * in correct way. Both pages are locked so we cannot race with uncharge.
|
||||
+ */
|
||||
+void mem_cgroup_replace_page_cache(struct page *oldpage,
|
||||
+ struct page *newpage)
|
||||
+{
|
||||
+ struct mem_cgroup *memcg;
|
||||
+ struct page_cgroup *pc;
|
||||
+ struct zone *zone;
|
||||
+ enum charge_type type = MEM_CGROUP_CHARGE_TYPE_CACHE;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ if (mem_cgroup_disabled())
|
||||
+ return;
|
||||
+
|
||||
+ pc = lookup_page_cgroup(oldpage);
|
||||
+ /* fix accounting on old pages */
|
||||
+ lock_page_cgroup(pc);
|
||||
+ memcg = pc->mem_cgroup;
|
||||
+ mem_cgroup_charge_statistics(memcg, PageCgroupCache(pc), -1);
|
||||
+ ClearPageCgroupUsed(pc);
|
||||
+ unlock_page_cgroup(pc);
|
||||
+
|
||||
+ if (PageSwapBacked(oldpage))
|
||||
+ type = MEM_CGROUP_CHARGE_TYPE_SHMEM;
|
||||
+
|
||||
+ zone = page_zone(newpage);
|
||||
+ pc = lookup_page_cgroup(newpage);
|
||||
+ /*
|
||||
+ * Even if newpage->mapping was NULL before starting replacement,
|
||||
+ * the newpage may be on LRU(or pagevec for LRU) already. We lock
|
||||
+ * LRU while we overwrite pc->mem_cgroup.
|
||||
+ */
|
||||
+ spin_lock_irqsave(&zone->lru_lock, flags);
|
||||
+ if (PageLRU(newpage))
|
||||
+ del_page_from_lru_list(zone, newpage, page_lru(newpage));
|
||||
+ __mem_cgroup_commit_charge(memcg, newpage, 1, pc, type);
|
||||
+ if (PageLRU(newpage))
|
||||
+ add_page_to_lru_list(zone, newpage, page_lru(newpage));
|
||||
+ spin_unlock_irqrestore(&zone->lru_lock, flags);
|
||||
+}
|
||||
+
|
||||
#ifdef CONFIG_DEBUG_VM
|
||||
static struct page_cgroup *lookup_page_cgroup_used(struct page *page)
|
||||
{
|
||||
--
|
||||
1.7.7.4
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user