Linux 3.3.1
This commit is contained in:
parent
e9cafbfe1a
commit
5be33f56fa
|
@ -1,48 +0,0 @@
|
|||
Commit 4949be16822e92a18ea0cc1616319926628092ee changed the behaviour of
|
||||
pcie_aspm_sanity_check() to always return 0 if aspm is disabled, in order
|
||||
to avoid cases where we changed ASPM state on pre-PCIe 1.1 devices. This
|
||||
skipped the secondary function of pcie_aspm_sanity_check which was to avoid
|
||||
us enabling ASPM on devices that had non-PCIe children, causing us to hit
|
||||
a BUG_ON later on. Move the aspm_disabled check so we continue to honour
|
||||
that scenario.
|
||||
|
||||
Signed-off-by: Matthew Garrett <mjg@redhat.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
---
|
||||
drivers/pci/pcie/aspm.c | 13 ++++++++++---
|
||||
1 files changed, 10 insertions(+), 3 deletions(-)
|
||||
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
|
||||
index 86111d9..41e367b 100644
|
||||
--- a/drivers/pci/pcie/aspm.c
|
||||
+++ b/drivers/pci/pcie/aspm.c
|
||||
@@ -521,9 +521,6 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
|
||||
int pos;
|
||||
u32 reg32;
|
||||
|
||||
- if (aspm_disabled)
|
||||
- return 0;
|
||||
-
|
||||
/*
|
||||
* Some functions in a slot might not all be PCIe functions,
|
||||
* very strange. Disable ASPM for the whole slot
|
||||
@@ -532,6 +529,16 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
|
||||
pos = pci_pcie_cap(child);
|
||||
if (!pos)
|
||||
return -EINVAL;
|
||||
+
|
||||
+ /*
|
||||
+ * If ASPM is disabled then we're not going to change
|
||||
+ * the BIOS state. It's safe to continue even if it's a
|
||||
+ * pre-1.1 device
|
||||
+ */
|
||||
+
|
||||
+ if (aspm_disabled)
|
||||
+ continue;
|
||||
+
|
||||
/*
|
||||
* Disable ASPM for pre-1.1 PCIe device, we follow MS to use
|
||||
* RBER bit to determine if a function is 1.1 version device
|
||||
--
|
||||
1.7.7.6
|
||||
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
From 3fa016a0b5c5237e9c387fc3249592b2cb5391c6 Mon Sep 17 00:00:00 2001
|
||||
From: Dave Airlie <airlied@redhat.com>
|
||||
Date: Wed, 28 Mar 2012 10:48:49 +0100
|
||||
Subject: [PATCH] drm/i915: suspend fbdev device around suspend/hibernate
|
||||
|
||||
Looking at hibernate overwriting I though it looked like a cursor,
|
||||
so I tracked down this missing piece to stop the cursor blink
|
||||
timer. I've no idea if this is sufficient to fix the hibernate
|
||||
problems people are seeing, but please test it.
|
||||
|
||||
Both radeon and nouveau have done this for a long time.
|
||||
|
||||
I've run this personally all night hib/resume cycles with no fails.
|
||||
|
||||
Reviewed-by: Keith Packard <keithp@keithp.com>
|
||||
Reported-by: Petr Tesarik <kernel@tesarici.cz>
|
||||
Reported-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
Reported-by: Lots of misc segfaults after hibernate across the world.
|
||||
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=37142
|
||||
Tested-by: Dave Airlie <airlied@redhat.com>
|
||||
Tested-by: Bojan Smojver <bojan@rexursive.com>
|
||||
Tested-by: Andreas Hartmann <andihartmann@01019freenet.de>
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
---
|
||||
drivers/gpu/drm/i915/i915_drv.c | 7 +++++++
|
||||
drivers/gpu/drm/i915/intel_drv.h | 2 +-
|
||||
drivers/gpu/drm/i915/intel_fb.c | 10 ++++++++++
|
||||
3 files changed, 18 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
|
||||
index 0694e17..1a7559b 100644
|
||||
--- a/drivers/gpu/drm/i915/i915_drv.c
|
||||
+++ b/drivers/gpu/drm/i915/i915_drv.c
|
||||
@@ -467,6 +467,10 @@ static int i915_drm_freeze(struct drm_device *dev)
|
||||
/* Modeset on resume, not lid events */
|
||||
dev_priv->modeset_on_lid = 0;
|
||||
|
||||
+ console_lock();
|
||||
+ intel_fbdev_set_suspend(dev, 1);
|
||||
+ console_unlock();
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -539,6 +543,9 @@ static int i915_drm_thaw(struct drm_device *dev)
|
||||
|
||||
dev_priv->modeset_on_lid = 0;
|
||||
|
||||
+ console_lock();
|
||||
+ intel_fbdev_set_suspend(dev, 0);
|
||||
+ console_unlock();
|
||||
return error;
|
||||
}
|
||||
|
||||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
|
||||
index 9cec6c3..5a14149 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_drv.h
|
||||
+++ b/drivers/gpu/drm/i915/intel_drv.h
|
||||
@@ -382,7 +382,7 @@ extern int intel_framebuffer_init(struct drm_device *dev,
|
||||
struct drm_i915_gem_object *obj);
|
||||
extern int intel_fbdev_init(struct drm_device *dev);
|
||||
extern void intel_fbdev_fini(struct drm_device *dev);
|
||||
-
|
||||
+extern void intel_fbdev_set_suspend(struct drm_device *dev, int state);
|
||||
extern void intel_prepare_page_flip(struct drm_device *dev, int plane);
|
||||
extern void intel_finish_page_flip(struct drm_device *dev, int pipe);
|
||||
extern void intel_finish_page_flip_plane(struct drm_device *dev, int plane);
|
||||
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c
|
||||
index 2d87669..19ecd78 100644
|
||||
--- a/drivers/gpu/drm/i915/intel_fb.c
|
||||
+++ b/drivers/gpu/drm/i915/intel_fb.c
|
||||
@@ -254,6 +254,16 @@ void intel_fbdev_fini(struct drm_device *dev)
|
||||
kfree(dev_priv->fbdev);
|
||||
dev_priv->fbdev = NULL;
|
||||
}
|
||||
+
|
||||
+void intel_fbdev_set_suspend(struct drm_device *dev, int state)
|
||||
+{
|
||||
+ drm_i915_private_t *dev_priv = dev->dev_private;
|
||||
+ if (!dev_priv->fbdev)
|
||||
+ return;
|
||||
+
|
||||
+ fb_set_suspend(dev_priv->fbdev->helper.fbdev, state);
|
||||
+}
|
||||
+
|
||||
MODULE_LICENSE("GPL and additional rights");
|
||||
|
||||
void intel_fb_output_poll_changed(struct drm_device *dev)
|
||||
--
|
||||
1.7.7.6
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
Path: news.gmane.org!not-for-mail
|
||||
From: Eric Sandeen <sandeen@redhat.com>
|
||||
Newsgroups: gmane.comp.file-systems.ext4
|
||||
Subject: [PATCH] jbd2: clear BH_Delay & BH_Unwritten in journal_unmap_buffer
|
||||
Date: Tue, 07 Feb 2012 16:07:20 -0600
|
||||
Lines: 42
|
||||
Approved: news@gmane.org
|
||||
Message-ID: <4F31A098.4050601@redhat.com>
|
||||
NNTP-Posting-Host: plane.gmane.org
|
||||
Mime-Version: 1.0
|
||||
Content-Type: text/plain; charset=ISO-8859-1
|
||||
Content-Transfer-Encoding: 7bit
|
||||
X-Trace: dough.gmane.org 1328656072 12026 80.91.229.3 (7 Feb 2012 23:07:52 GMT)
|
||||
X-Complaints-To: usenet@dough.gmane.org
|
||||
NNTP-Posting-Date: Tue, 7 Feb 2012 23:07:52 +0000 (UTC)
|
||||
To: ext4 development <linux-ext4@vger.kernel.org>
|
||||
Original-X-From: linux-ext4-owner@vger.kernel.org Wed Feb 08 00:07:52 2012
|
||||
Return-path: <linux-ext4-owner@vger.kernel.org>
|
||||
Envelope-to: gcfe-linux-ext4@plane.gmane.org
|
||||
Original-Received: from vger.kernel.org ([209.132.180.67])
|
||||
by plane.gmane.org with esmtp (Exim 4.69)
|
||||
(envelope-from <linux-ext4-owner@vger.kernel.org>)
|
||||
id 1Ruu8d-0000lK-5P
|
||||
for gcfe-linux-ext4@plane.gmane.org; Wed, 08 Feb 2012 00:07:51 +0100
|
||||
Original-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
|
||||
id S1756187Ab2BGXHt (ORCPT <rfc822;gcfe-linux-ext4@m.gmane.org>);
|
||||
Tue, 7 Feb 2012 18:07:49 -0500
|
||||
Original-Received: from mx1.redhat.com ([209.132.183.28]:19432 "EHLO mx1.redhat.com"
|
||||
rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP
|
||||
id S1753992Ab2BGXHs (ORCPT <rfc822;linux-ext4@vger.kernel.org>);
|
||||
Tue, 7 Feb 2012 18:07:48 -0500
|
||||
Original-Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11])
|
||||
by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q17N7dj0027622
|
||||
(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK)
|
||||
for <linux-ext4@vger.kernel.org>; Tue, 7 Feb 2012 18:07:48 -0500
|
||||
Original-Received: from liberator.sandeen.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1])
|
||||
by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q17M7Kgt001990
|
||||
(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO)
|
||||
for <linux-ext4@vger.kernel.org>; Tue, 7 Feb 2012 17:07:21 -0500
|
||||
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:10.0) Gecko/20120129 Thunderbird/10.0
|
||||
X-Enigmail-Version: 1.3.5
|
||||
X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11
|
||||
Original-Sender: linux-ext4-owner@vger.kernel.org
|
||||
Precedence: bulk
|
||||
List-ID: <linux-ext4.vger.kernel.org>
|
||||
X-Mailing-List: linux-ext4@vger.kernel.org
|
||||
Xref: news.gmane.org gmane.comp.file-systems.ext4:30623
|
||||
Archived-At: <http://permalink.gmane.org/gmane.comp.file-systems.ext4/30623>
|
||||
|
||||
journal_unmap_buffer()'s zap_buffer: code clears a lot of buffer head
|
||||
state ala discard_buffer(), but does not touch _Delay or _Unwritten
|
||||
as discard_buffer() does.
|
||||
|
||||
This can be problematic in some areas of the ext4 code which assume
|
||||
that if they have found a buffer marked unwritten or delay, then it's
|
||||
a live one. Perhaps those spots should check whether it is mapped
|
||||
as well, but if jbd2 is going to tear down a buffer, let's really
|
||||
tear it down completely.
|
||||
|
||||
Without this I get some fsx failures on sub-page-block filesystems
|
||||
up until v3.2, at which point 4e96b2dbbf1d7e81f22047a50f862555a6cb87cb
|
||||
and 189e868fa8fdca702eb9db9d8afc46b5cb9144c9 make the failures go
|
||||
away, because buried within that large change is some more flag
|
||||
clearing. I still think it's worth doing in jbd2, since
|
||||
->invalidatepage leads here directly, and it's the right place
|
||||
to clear away these flags.
|
||||
|
||||
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
---
|
||||
|
||||
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
|
||||
index 35ae096..52653306 100644
|
||||
--- a/fs/jbd2/transaction.c
|
||||
+++ b/fs/jbd2/transaction.c
|
||||
@@ -1949,6 +1949,8 @@ zap_buffer_unlocked:
|
||||
clear_buffer_mapped(bh);
|
||||
clear_buffer_req(bh);
|
||||
clear_buffer_new(bh);
|
||||
+ clear_buffer_delay(bh);
|
||||
+ clear_buffer_unwritten(bh);
|
||||
bh->b_bdev = NULL;
|
||||
return may_free;
|
||||
}
|
||||
|
||||
|
||||
--
|
||||
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
||||
|
42
kernel.spec
42
kernel.spec
|
@ -54,7 +54,7 @@ Summary: The Linux kernel
|
|||
# For non-released -rc kernels, this will be appended after the rcX and
|
||||
# gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
|
||||
#
|
||||
%global baserelease 9
|
||||
%global baserelease 1
|
||||
%global fedora_build %{baserelease}
|
||||
|
||||
# base_sublevel is the kernel version we're starting with and patching
|
||||
|
@ -66,7 +66,7 @@ Summary: The Linux kernel
|
|||
%if 0%{?released_kernel}
|
||||
|
||||
# Do we have a -stable update to apply?
|
||||
%define stable_update 0
|
||||
%define stable_update 1
|
||||
# Is it a -stable RC?
|
||||
%define stable_rc 0
|
||||
# Set rpm version accordingly
|
||||
|
@ -686,7 +686,6 @@ Patch1800: drm-vgem.patch
|
|||
# intel drm is all merged upstream
|
||||
Patch1824: drm-intel-next.patch
|
||||
Patch1825: drm-i915-dp-stfu.patch
|
||||
Patch1827: drm-i915-suspend-fbdev-device-around-suspend-hiberna.patch
|
||||
|
||||
Patch1900: linux-2.6-intel-iommu-igfx.patch
|
||||
|
||||
|
@ -738,8 +737,6 @@ Patch21010: highbank-export-clock-functions.patch
|
|||
|
||||
Patch21070: ext4-Support-check-none-nocheck-mount-options.patch
|
||||
|
||||
Patch21092: udlfb-remove-sysfs-framebuffer-device-with-USB-disconnect.patch
|
||||
|
||||
Patch21093: rt2x00_fix_MCU_request_failures.patch
|
||||
|
||||
Patch21094: power-x86-destdir.patch
|
||||
|
@ -747,35 +744,24 @@ Patch21094: power-x86-destdir.patch
|
|||
Patch21095: hfsplus-Change-finder_info-to-u32.patch
|
||||
Patch21096: hfsplus-Add-an-ioctl-to-bless-files.patch
|
||||
|
||||
#rhbz 788260
|
||||
Patch21233: jbd2-clear-BH_Delay-and-BH_Unwritten-in-journal_unmap_buf.patch
|
||||
|
||||
#rhbz 754518
|
||||
Patch21235: scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch
|
||||
|
||||
Patch21250: mcelog-rcu-splat.patch
|
||||
Patch21270: x86-Avoid-invoking-RCU-when-CPU-is-idle.patch
|
||||
|
||||
#rhbz 795544
|
||||
Patch21290: ums_realtek-do-not-use-stack-memory-for-DMA-in-__do_.patch
|
||||
|
||||
#rhbz 727865 730007
|
||||
Patch21300: ACPICA-Fix-regression-in-FADT-revision-checks.patch
|
||||
|
||||
#rhbz 728478
|
||||
Patch21302: sony-laptop-Enable-keyboard-backlight-by-default.patch
|
||||
|
||||
#rhbz 803809 CVE-2012-1179
|
||||
Patch21304: mm-thp-fix-pmd_bad-triggering.patch
|
||||
|
||||
#rhbz 804007
|
||||
Patch21305: mac80211-fix-possible-tid_rx-reorder_timer-use-after-free.patch
|
||||
|
||||
#rhbz 804957 CVE-2012-1568
|
||||
Patch21306: shlib_base_randomize.patch
|
||||
|
||||
Patch21350: x86-ioapic-add-register-checks-for-bogus-io-apic-entries.patch
|
||||
|
||||
#rhbz 804347
|
||||
Patch21351: x86-add-io_apic_ops-to-allow-interception.patch
|
||||
Patch21352: x86-apic_ops-Replace-apic_ops-with-x86_apic_ops.patch
|
||||
|
@ -787,7 +773,6 @@ Patch21371: iwlwifi-do-not-nulify-ctx-vif-on-reset.patch
|
|||
|
||||
Patch21400: unhandled-irqs-switch-to-polling.patch
|
||||
|
||||
Patch21500: ASPM-Fix-pcie-devs-with-non-pcie-children.patch
|
||||
Patch21501: nfs-Fix-length-of-buffer-copied-in-__nfs4_get_acl_uncached.patch
|
||||
|
||||
#rhbz 808207 CVE-2012-1601
|
||||
|
@ -1444,8 +1429,6 @@ ApplyPatch drm-i915-dp-stfu.patch
|
|||
|
||||
ApplyPatch linux-2.6-intel-iommu-igfx.patch
|
||||
|
||||
ApplyPatch drm-i915-suspend-fbdev-device-around-suspend-hiberna.patch
|
||||
|
||||
# silence the ACPI blacklist code
|
||||
ApplyPatch linux-2.6-silence-acpi-blacklist.patch
|
||||
ApplyPatch quite-apm.patch
|
||||
|
@ -1465,7 +1448,8 @@ ApplyPatch dmar-disable-when-ricoh-multifunction.patch
|
|||
|
||||
ApplyPatch efi-dont-map-boot-services-on-32bit.patch
|
||||
|
||||
ApplyPatch hibernate-freeze-filesystems.patch
|
||||
#FIXME
|
||||
#ApplyPatch hibernate-freeze-filesystems.patch
|
||||
|
||||
ApplyPatch lis3-improve-handling-of-null-rate.patch
|
||||
|
||||
|
@ -1478,8 +1462,6 @@ ApplyPatch utrace.patch
|
|||
|
||||
ApplyPatch ext4-Support-check-none-nocheck-mount-options.patch
|
||||
|
||||
ApplyPatch udlfb-remove-sysfs-framebuffer-device-with-USB-disconnect.patch
|
||||
|
||||
#rhbz 772772
|
||||
ApplyPatch rt2x00_fix_MCU_request_failures.patch
|
||||
|
||||
|
@ -1488,17 +1470,11 @@ ApplyPatch power-x86-destdir.patch
|
|||
ApplyPatch hfsplus-Change-finder_info-to-u32.patch
|
||||
ApplyPatch hfsplus-Add-an-ioctl-to-bless-files.patch
|
||||
|
||||
#rhbz 788269
|
||||
ApplyPatch jbd2-clear-BH_Delay-and-BH_Unwritten-in-journal_unmap_buf.patch
|
||||
|
||||
#rhbz 754518
|
||||
ApplyPatch scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch
|
||||
|
||||
ApplyPatch mcelog-rcu-splat.patch
|
||||
|
||||
#rhbz 795544
|
||||
ApplyPatch ums_realtek-do-not-use-stack-memory-for-DMA-in-__do_.patch
|
||||
|
||||
#rhbz 727865 730007
|
||||
ApplyPatch ACPICA-Fix-regression-in-FADT-revision-checks.patch
|
||||
|
||||
|
@ -1515,8 +1491,6 @@ ApplyPatch unhandled-irqs-switch-to-polling.patch
|
|||
|
||||
ApplyPatch weird-root-dentry-name-debug.patch
|
||||
|
||||
ApplyPatch x86-ioapic-add-register-checks-for-bogus-io-apic-entries.patch
|
||||
|
||||
#rhbz 804347
|
||||
ApplyPatch x86-add-io_apic_ops-to-allow-interception.patch
|
||||
ApplyPatch x86-apic_ops-Replace-apic_ops-with-x86_apic_ops.patch
|
||||
|
@ -1526,14 +1500,9 @@ ApplyPatch xen-x86-Implement-x86_apic_ops.patch
|
|||
ApplyPatch iwlegacy-do-not-nulify-il-vif-on-reset.patch
|
||||
ApplyPatch iwlwifi-do-not-nulify-ctx-vif-on-reset.patch
|
||||
|
||||
#rhbz 803809 CVE-2012-1179
|
||||
ApplyPatch mm-thp-fix-pmd_bad-triggering.patch
|
||||
|
||||
#Highbank clock functions
|
||||
ApplyPatch highbank-export-clock-functions.patch
|
||||
|
||||
ApplyPatch ASPM-Fix-pcie-devs-with-non-pcie-children.patch
|
||||
|
||||
ApplyPatch nfs-Fix-length-of-buffer-copied-in-__nfs4_get_acl_uncached.patch
|
||||
|
||||
#rhbz 808207 CVE-2012-1601
|
||||
|
@ -2378,6 +2347,9 @@ fi
|
|||
# '-' | |
|
||||
# '-'
|
||||
%changelog
|
||||
* Mon Apr 02 2012 Dave Jones <davej@redhat.com> 3.3.1-1
|
||||
- Linux 3.3.1
|
||||
|
||||
* Fri Mar 30 2012 Dave Jones <davej@redhat.com>
|
||||
- Silence the timekeeping "Adjusting tsc more then 11%" spew. (rhbz 798600)
|
||||
|
||||
|
|
|
@ -1,447 +0,0 @@
|
|||
In some cases it may happen that pmd_none_or_clear_bad() is called
|
||||
with the mmap_sem hold in read mode. In those cases the huge page
|
||||
faults can allocate hugepmds under pmd_none_or_clear_bad() and that
|
||||
can trigger a false positive from pmd_bad() that will not like to see
|
||||
a pmd materializing as trans huge.
|
||||
|
||||
It's not khugepaged the problem, khugepaged holds the mmap_sem in
|
||||
write mode (and all those sites must hold the mmap_sem in read mode to
|
||||
prevent pagetables to go away from under them, during code review it
|
||||
seems vm86 mode on 32bit kernels requires that too unless it's
|
||||
restricted to 1 thread per process or UP builds). The race is only
|
||||
with the huge pagefaults that can convert a pmd_none() into a
|
||||
pmd_trans_huge().
|
||||
|
||||
Effectively all these pmd_none_or_clear_bad() sites running with
|
||||
mmap_sem in read mode are somewhat speculative with the page faults,
|
||||
and the result is always undefined when they run simultaneously. This
|
||||
is probably why it wasn't common to run into this. For example if the
|
||||
madvise(MADV_DONTNEED) runs zap_page_range() shortly before the page
|
||||
fault, the hugepage will not be zapped, if the page fault runs first
|
||||
it will be zapped.
|
||||
|
||||
Altering pmd_bad() not to error out if it finds hugepmds won't be
|
||||
enough to fix this, because zap_pmd_range would then proceed to call
|
||||
zap_pte_range (which would be incorrect if the pmd become a
|
||||
pmd_trans_huge()).
|
||||
|
||||
The simplest way to fix this is to read the pmd in the local stack
|
||||
(regardless of what we read, no need of actual CPU barriers, only
|
||||
compiler barrier needed), and be sure it is not changing under the
|
||||
code that computes its value. Even if the real pmd is changing under
|
||||
the value we hold on the stack, we don't care. If we actually end up
|
||||
in zap_pte_range it means the pmd was not none already and it was not
|
||||
huge, and it can't become huge from under us (khugepaged locking
|
||||
explained above).
|
||||
|
||||
All we need is to enforce that there is no way anymore that in a code
|
||||
path like below, pmd_trans_huge can be false, but
|
||||
pmd_none_or_clear_bad can run into a hugepmd. The overhead of a
|
||||
barrier() is just a compiler tweak and should not be measurable (I
|
||||
only added it for THP builds). I don't exclude different compiler
|
||||
versions may have prevented the race too by caching the value of *pmd
|
||||
on the stack (that hasn't been verified, but it wouldn't be impossible
|
||||
considering pmd_none_or_clear_bad, pmd_bad, pmd_trans_huge, pmd_none
|
||||
are all inlines and there's no external function called in between
|
||||
pmd_trans_huge and pmd_none_or_clear_bad).
|
||||
|
||||
if (pmd_trans_huge(*pmd)) {
|
||||
if (next-addr != HPAGE_PMD_SIZE) {
|
||||
VM_BUG_ON(!rwsem_is_locked(&tlb->mm->mmap_sem));
|
||||
split_huge_page_pmd(vma->vm_mm, pmd);
|
||||
} else if (zap_huge_pmd(tlb, vma, pmd, addr))
|
||||
continue;
|
||||
/* fall through */
|
||||
}
|
||||
if (pmd_none_or_clear_bad(pmd))
|
||||
|
||||
Because this race condition could be exercised without special
|
||||
privileges this was reported in CVE-2012-1179.
|
||||
|
||||
The race was identified and fully explained by Ulrich who debugged it.
|
||||
I'm quoting his accurate explanation below, for reference.
|
||||
|
||||
====== start quote =======
|
||||
mapcount 0 page_mapcount 1
|
||||
kernel BUG at mm/huge_memory.c:1384!
|
||||
|
||||
At some point prior to the panic, a "bad pmd ..." message similar to the
|
||||
following is logged on the console:
|
||||
|
||||
mm/memory.c:145: bad pmd ffff8800376e1f98(80000000314000e7).
|
||||
|
||||
The "bad pmd ..." message is logged by pmd_clear_bad() before it clears
|
||||
the page's PMD table entry.
|
||||
|
||||
143 void pmd_clear_bad(pmd_t *pmd)
|
||||
144 {
|
||||
-> 145 pmd_ERROR(*pmd);
|
||||
146 pmd_clear(pmd);
|
||||
147 }
|
||||
|
||||
After the PMD table entry has been cleared, there is an inconsistency
|
||||
between the actual number of PMD table entries that are mapping the page
|
||||
and the page's map count (_mapcount field in struct page). When the page
|
||||
is subsequently reclaimed, __split_huge_page() detects this inconsistency.
|
||||
|
||||
1381 if (mapcount != page_mapcount(page))
|
||||
1382 printk(KERN_ERR "mapcount %d page_mapcount %d\n",
|
||||
1383 mapcount, page_mapcount(page));
|
||||
-> 1384 BUG_ON(mapcount != page_mapcount(page));
|
||||
|
||||
The root cause of the problem is a race of two threads in a multithreaded
|
||||
process. Thread B incurs a page fault on a virtual address that has never
|
||||
been accessed (PMD entry is zero) while Thread A is executing an madvise()
|
||||
system call on a virtual address within the same 2 MB (huge page) range.
|
||||
|
||||
virtual address space
|
||||
.---------------------.
|
||||
| |
|
||||
| |
|
||||
.-|---------------------|
|
||||
| | |
|
||||
| | |<-- B(fault)
|
||||
| | |
|
||||
2 MB | |/////////////////////|-.
|
||||
huge < |/////////////////////| > A(range)
|
||||
page | |/////////////////////|-'
|
||||
| | |
|
||||
| | |
|
||||
'-|---------------------|
|
||||
| |
|
||||
| |
|
||||
'---------------------'
|
||||
|
||||
- Thread A is executing an madvise(..., MADV_DONTNEED) system call
|
||||
on the virtual address range "A(range)" shown in the picture.
|
||||
|
||||
sys_madvise
|
||||
// Acquire the semaphore in shared mode.
|
||||
down_read(¤t->mm->mmap_sem)
|
||||
...
|
||||
madvise_vma
|
||||
switch (behavior)
|
||||
case MADV_DONTNEED:
|
||||
madvise_dontneed
|
||||
zap_page_range
|
||||
unmap_vmas
|
||||
unmap_page_range
|
||||
zap_pud_range
|
||||
zap_pmd_range
|
||||
//
|
||||
// Assume that this huge page has never been accessed.
|
||||
// I.e. content of the PMD entry is zero (not mapped).
|
||||
//
|
||||
if (pmd_trans_huge(*pmd)) {
|
||||
// We don't get here due to the above assumption.
|
||||
}
|
||||
//
|
||||
// Assume that Thread B incurred a page fault and
|
||||
.---------> // sneaks in here as shown below.
|
||||
| //
|
||||
| if (pmd_none_or_clear_bad(pmd))
|
||||
| {
|
||||
| if (unlikely(pmd_bad(*pmd)))
|
||||
| pmd_clear_bad
|
||||
| {
|
||||
| pmd_ERROR
|
||||
| // Log "bad pmd ..." message here.
|
||||
| pmd_clear
|
||||
| // Clear the page's PMD entry.
|
||||
| // Thread B incremented the map count
|
||||
| // in page_add_new_anon_rmap(), but
|
||||
| // now the page is no longer mapped
|
||||
| // by a PMD entry (-> inconsistency).
|
||||
| }
|
||||
| }
|
||||
|
|
||||
v
|
||||
- Thread B is handling a page fault on virtual address "B(fault)" shown
|
||||
in the picture.
|
||||
|
||||
...
|
||||
do_page_fault
|
||||
__do_page_fault
|
||||
// Acquire the semaphore in shared mode.
|
||||
down_read_trylock(&mm->mmap_sem)
|
||||
...
|
||||
handle_mm_fault
|
||||
if (pmd_none(*pmd) && transparent_hugepage_enabled(vma))
|
||||
// We get here due to the above assumption (PMD entry is zero).
|
||||
do_huge_pmd_anonymous_page
|
||||
alloc_hugepage_vma
|
||||
// Allocate a new transparent huge page here.
|
||||
...
|
||||
__do_huge_pmd_anonymous_page
|
||||
...
|
||||
spin_lock(&mm->page_table_lock)
|
||||
...
|
||||
page_add_new_anon_rmap
|
||||
// Here we increment the page's map count (starts at -1).
|
||||
atomic_set(&page->_mapcount, 0)
|
||||
set_pmd_at
|
||||
// Here we set the page's PMD entry which will be cleared
|
||||
// when Thread A calls pmd_clear_bad().
|
||||
...
|
||||
spin_unlock(&mm->page_table_lock)
|
||||
|
||||
The mmap_sem does not prevent the race because both threads are acquiring
|
||||
it in shared mode (down_read). Thread B holds the page_table_lock while
|
||||
the page's map count and PMD table entry are updated. However, Thread A
|
||||
does not synchronize on that lock.
|
||||
====== end quote =======
|
||||
|
||||
Reported-by: Ulrich Obergfell <uobergfe@redhat.com>
|
||||
Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
|
||||
---
|
||||
arch/x86/kernel/vm86_32.c | 2 +
|
||||
fs/proc/task_mmu.c | 9 ++++++
|
||||
include/asm-generic/pgtable.h | 57 +++++++++++++++++++++++++++++++++++++++++
|
||||
mm/memcontrol.c | 4 +++
|
||||
mm/memory.c | 14 ++++++++--
|
||||
mm/mempolicy.c | 2 +-
|
||||
mm/mincore.c | 2 +-
|
||||
mm/pagewalk.c | 2 +-
|
||||
mm/swapfile.c | 4 +--
|
||||
9 files changed, 87 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
|
||||
index b466cab..328cb37 100644
|
||||
--- a/arch/x86/kernel/vm86_32.c
|
||||
+++ b/arch/x86/kernel/vm86_32.c
|
||||
@@ -172,6 +172,7 @@ static void mark_screen_rdonly(struct mm_struct *mm)
|
||||
spinlock_t *ptl;
|
||||
int i;
|
||||
|
||||
+ down_write(&mm->mmap_sem);
|
||||
pgd = pgd_offset(mm, 0xA0000);
|
||||
if (pgd_none_or_clear_bad(pgd))
|
||||
goto out;
|
||||
@@ -190,6 +191,7 @@ static void mark_screen_rdonly(struct mm_struct *mm)
|
||||
}
|
||||
pte_unmap_unlock(pte, ptl);
|
||||
out:
|
||||
+ up_write(&mm->mmap_sem);
|
||||
flush_tlb();
|
||||
}
|
||||
|
||||
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
|
||||
index 7dcd2a2..3efa725 100644
|
||||
--- a/fs/proc/task_mmu.c
|
||||
+++ b/fs/proc/task_mmu.c
|
||||
@@ -409,6 +409,9 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
|
||||
} else {
|
||||
spin_unlock(&walk->mm->page_table_lock);
|
||||
}
|
||||
+
|
||||
+ if (pmd_trans_unstable(pmd))
|
||||
+ return 0;
|
||||
/*
|
||||
* The mmap_sem held all the way back in m_start() is what
|
||||
* keeps khugepaged out of here and from collapsing things
|
||||
@@ -507,6 +510,8 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr,
|
||||
struct page *page;
|
||||
|
||||
split_huge_page_pmd(walk->mm, pmd);
|
||||
+ if (pmd_trans_unstable(pmd))
|
||||
+ return 0;
|
||||
|
||||
pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
|
||||
for (; addr != end; pte++, addr += PAGE_SIZE) {
|
||||
@@ -670,6 +675,8 @@ static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
|
||||
int err = 0;
|
||||
|
||||
split_huge_page_pmd(walk->mm, pmd);
|
||||
+ if (pmd_trans_unstable(pmd))
|
||||
+ return 0;
|
||||
|
||||
/* find the first VMA at or above 'addr' */
|
||||
vma = find_vma(walk->mm, addr);
|
||||
@@ -961,6 +968,8 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr,
|
||||
spin_unlock(&walk->mm->page_table_lock);
|
||||
}
|
||||
|
||||
+ if (pmd_trans_unstable(pmd))
|
||||
+ return 0;
|
||||
orig_pte = pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
|
||||
do {
|
||||
struct page *page = can_gather_numa_stats(*pte, md->vma, addr);
|
||||
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
|
||||
index 76bff2b..10f8291 100644
|
||||
--- a/include/asm-generic/pgtable.h
|
||||
+++ b/include/asm-generic/pgtable.h
|
||||
@@ -443,6 +443,63 @@ static inline int pmd_write(pmd_t pmd)
|
||||
#endif /* __HAVE_ARCH_PMD_WRITE */
|
||||
#endif
|
||||
|
||||
+/*
|
||||
+ * This function is meant to be used by sites walking pagetables with
|
||||
+ * the mmap_sem hold in read mode to protect against MADV_DONTNEED and
|
||||
+ * transhuge page faults. MADV_DONTNEED can convert a transhuge pmd
|
||||
+ * into a null pmd and the transhuge page fault can convert a null pmd
|
||||
+ * into an hugepmd or into a regular pmd (if the hugepage allocation
|
||||
+ * fails). While holding the mmap_sem in read mode the pmd becomes
|
||||
+ * stable and stops changing under us only if it's not null and not a
|
||||
+ * transhuge pmd. When those races occurs and this function makes a
|
||||
+ * difference vs the standard pmd_none_or_clear_bad, the result is
|
||||
+ * undefined so behaving like if the pmd was none is safe (because it
|
||||
+ * can return none anyway). The compiler level barrier() is critically
|
||||
+ * important to compute the two checks atomically on the same pmdval.
|
||||
+ */
|
||||
+static inline int pmd_none_or_trans_huge_or_clear_bad(pmd_t *pmd)
|
||||
+{
|
||||
+ /* depend on compiler for an atomic pmd read */
|
||||
+ pmd_t pmdval = *pmd;
|
||||
+ /*
|
||||
+ * The barrier will stabilize the pmdval in a register or on
|
||||
+ * the stack so that it will stop changing under the code.
|
||||
+ */
|
||||
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
+ barrier();
|
||||
+#endif
|
||||
+ if (pmd_none(pmdval))
|
||||
+ return 1;
|
||||
+ if (unlikely(pmd_bad(pmdval))) {
|
||||
+ if (!pmd_trans_huge(pmdval))
|
||||
+ pmd_clear_bad(pmd);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This is a noop if Transparent Hugepage Support is not built into
|
||||
+ * the kernel. Otherwise it is equivalent to
|
||||
+ * pmd_none_or_trans_huge_or_clear_bad(), and shall only be called in
|
||||
+ * places that already verified the pmd is not none and they want to
|
||||
+ * walk ptes while holding the mmap sem in read mode (write mode don't
|
||||
+ * need this). If THP is not enabled, the pmd can't go away under the
|
||||
+ * code even if MADV_DONTNEED runs, but if THP is enabled we need to
|
||||
+ * run a pmd_trans_unstable before walking the ptes after
|
||||
+ * split_huge_page_pmd returns (because it may have run when the pmd
|
||||
+ * become null, but then a page fault can map in a THP and not a
|
||||
+ * regular page).
|
||||
+ */
|
||||
+static inline int pmd_trans_unstable(pmd_t *pmd)
|
||||
+{
|
||||
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
+ return pmd_none_or_trans_huge_or_clear_bad(pmd);
|
||||
+#else
|
||||
+ return 0;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_GENERIC_PGTABLE_H */
|
||||
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
|
||||
index d0e57a3..67b0578 100644
|
||||
--- a/mm/memcontrol.c
|
||||
+++ b/mm/memcontrol.c
|
||||
@@ -5193,6 +5193,8 @@ static int mem_cgroup_count_precharge_pte_range(pmd_t *pmd,
|
||||
spinlock_t *ptl;
|
||||
|
||||
split_huge_page_pmd(walk->mm, pmd);
|
||||
+ if (pmd_trans_unstable(pmd))
|
||||
+ return 0;
|
||||
|
||||
pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
|
||||
for (; addr != end; pte++, addr += PAGE_SIZE)
|
||||
@@ -5355,6 +5357,8 @@ static int mem_cgroup_move_charge_pte_range(pmd_t *pmd,
|
||||
spinlock_t *ptl;
|
||||
|
||||
split_huge_page_pmd(walk->mm, pmd);
|
||||
+ if (pmd_trans_unstable(pmd))
|
||||
+ return 0;
|
||||
retry:
|
||||
pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
|
||||
for (; addr != end; addr += PAGE_SIZE) {
|
||||
diff --git a/mm/memory.c b/mm/memory.c
|
||||
index fa2f04e..e3090fc 100644
|
||||
--- a/mm/memory.c
|
||||
+++ b/mm/memory.c
|
||||
@@ -1251,12 +1251,20 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb,
|
||||
VM_BUG_ON(!rwsem_is_locked(&tlb->mm->mmap_sem));
|
||||
split_huge_page_pmd(vma->vm_mm, pmd);
|
||||
} else if (zap_huge_pmd(tlb, vma, pmd, addr))
|
||||
- continue;
|
||||
+ goto next;
|
||||
/* fall through */
|
||||
}
|
||||
- if (pmd_none_or_clear_bad(pmd))
|
||||
- continue;
|
||||
+ /*
|
||||
+ * Here there can be other concurrent MADV_DONTNEED or
|
||||
+ * trans huge page faults running, and if the pmd is
|
||||
+ * none or trans huge it can change under us. This is
|
||||
+ * because MADV_DONTNEED holds the mmap_sem in read
|
||||
+ * mode.
|
||||
+ */
|
||||
+ if (pmd_none_or_trans_huge_or_clear_bad(pmd))
|
||||
+ goto next;
|
||||
next = zap_pte_range(tlb, vma, pmd, addr, next, details);
|
||||
+ next:
|
||||
cond_resched();
|
||||
} while (pmd++, addr = next, addr != end);
|
||||
|
||||
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
|
||||
index 47296fe..0a37570 100644
|
||||
--- a/mm/mempolicy.c
|
||||
+++ b/mm/mempolicy.c
|
||||
@@ -512,7 +512,7 @@ static inline int check_pmd_range(struct vm_area_struct *vma, pud_t *pud,
|
||||
do {
|
||||
next = pmd_addr_end(addr, end);
|
||||
split_huge_page_pmd(vma->vm_mm, pmd);
|
||||
- if (pmd_none_or_clear_bad(pmd))
|
||||
+ if (pmd_none_or_trans_huge_or_clear_bad(pmd))
|
||||
continue;
|
||||
if (check_pte_range(vma, pmd, addr, next, nodes,
|
||||
flags, private))
|
||||
diff --git a/mm/mincore.c b/mm/mincore.c
|
||||
index 636a868..936b4ce 100644
|
||||
--- a/mm/mincore.c
|
||||
+++ b/mm/mincore.c
|
||||
@@ -164,7 +164,7 @@ static void mincore_pmd_range(struct vm_area_struct *vma, pud_t *pud,
|
||||
}
|
||||
/* fall through */
|
||||
}
|
||||
- if (pmd_none_or_clear_bad(pmd))
|
||||
+ if (pmd_none_or_trans_huge_or_clear_bad(pmd))
|
||||
mincore_unmapped_range(vma, addr, next, vec);
|
||||
else
|
||||
mincore_pte_range(vma, pmd, addr, next, vec);
|
||||
diff --git a/mm/pagewalk.c b/mm/pagewalk.c
|
||||
index 2f5cf10..aa9701e 100644
|
||||
--- a/mm/pagewalk.c
|
||||
+++ b/mm/pagewalk.c
|
||||
@@ -59,7 +59,7 @@ again:
|
||||
continue;
|
||||
|
||||
split_huge_page_pmd(walk->mm, pmd);
|
||||
- if (pmd_none_or_clear_bad(pmd))
|
||||
+ if (pmd_none_or_trans_huge_or_clear_bad(pmd))
|
||||
goto again;
|
||||
err = walk_pte_range(pmd, addr, next, walk);
|
||||
if (err)
|
||||
diff --git a/mm/swapfile.c b/mm/swapfile.c
|
||||
index d999f09..f31b29d 100644
|
||||
--- a/mm/swapfile.c
|
||||
+++ b/mm/swapfile.c
|
||||
@@ -932,9 +932,7 @@ static inline int unuse_pmd_range(struct vm_area_struct *vma, pud_t *pud,
|
||||
pmd = pmd_offset(pud, addr);
|
||||
do {
|
||||
next = pmd_addr_end(addr, end);
|
||||
- if (unlikely(pmd_trans_huge(*pmd)))
|
||||
- continue;
|
||||
- if (pmd_none_or_clear_bad(pmd))
|
||||
+ if (pmd_none_or_trans_huge_or_clear_bad(pmd))
|
||||
continue;
|
||||
ret = unuse_pte_range(vma, pmd, addr, next, entry, page);
|
||||
if (ret)
|
||||
|
||||
--
|
||||
To unsubscribe, send a message with 'unsubscribe linux-mm' in
|
||||
the body to majordomo@kvack.org. For more info on Linux MM,
|
||||
see: http://www.linux-mm.org/ .
|
||||
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
|
||||
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
|
1
sources
1
sources
|
@ -1 +1,2 @@
|
|||
7133f5a2086a7d7ef97abac610c094f5 linux-3.3.tar.xz
|
||||
10771d657c5bf342bcfe66ed06653ecb patch-3.3.1.xz
|
||||
|
|
|
@ -1,118 +0,0 @@
|
|||
From 92a9c19a89af2ca219fbb040a0059f414a4b7223 Mon Sep 17 00:00:00 2001
|
||||
From: Kay Sievers <kay.sievers@vrfy.org>
|
||||
Date: Sat, 28 Jan 2012 19:57:46 +0000
|
||||
Subject: [PATCH] udlfb: remove sysfs framebuffer device with USB
|
||||
.disconnect()
|
||||
|
||||
The USB graphics card driver delays the unregistering of the framebuffer
|
||||
device to a workqueue, which breaks the userspace visible remove uevent
|
||||
sequence. Recent userspace tools started to support USB graphics card
|
||||
hotplug out-of-the-box and rely on proper events sent by the kernel.
|
||||
|
||||
The framebuffer device is a direct child of the USB interface which is
|
||||
removed immediately after the USB .disconnect() callback. But the fb device
|
||||
in /sys stays around until its final cleanup, at a time where all the parent
|
||||
devices have been removed already.
|
||||
|
||||
To work around that, we remove the sysfs fb device directly in the USB
|
||||
.disconnect() callback and leave only the cleanup of the internal fb
|
||||
data to the delayed work.
|
||||
|
||||
Before:
|
||||
add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)
|
||||
add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)
|
||||
add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb0 (graphics)
|
||||
remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)
|
||||
remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)
|
||||
remove /2-1.2:1.0/graphics/fb0 (graphics)
|
||||
|
||||
After:
|
||||
add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)
|
||||
add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)
|
||||
add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb1 (graphics)
|
||||
remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb1 (graphics)
|
||||
remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)
|
||||
remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Tested-by: Bernie Thompson <bernie@plugable.com>
|
||||
Acked-by: Bernie Thompson <bernie@plugable.com>
|
||||
Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
|
||||
Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
|
||||
---
|
||||
drivers/video/fbmem.c | 18 +++++++++++++++++-
|
||||
drivers/video/udlfb.c | 2 +-
|
||||
include/linux/fb.h | 1 +
|
||||
3 files changed, 19 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
|
||||
index ac9141b..c6ce416 100644
|
||||
--- a/drivers/video/fbmem.c
|
||||
+++ b/drivers/video/fbmem.c
|
||||
@@ -1665,6 +1665,7 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
+ unlink_framebuffer(fb_info);
|
||||
if (fb_info->pixmap.addr &&
|
||||
(fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
|
||||
kfree(fb_info->pixmap.addr);
|
||||
@@ -1672,7 +1673,6 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
|
||||
registered_fb[i] = NULL;
|
||||
num_registered_fb--;
|
||||
fb_cleanup_device(fb_info);
|
||||
- device_destroy(fb_class, MKDEV(FB_MAJOR, i));
|
||||
event.info = fb_info;
|
||||
fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
|
||||
|
||||
@@ -1681,6 +1681,22 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int unlink_framebuffer(struct fb_info *fb_info)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ i = fb_info->node;
|
||||
+ if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (fb_info->dev) {
|
||||
+ device_destroy(fb_class, MKDEV(FB_MAJOR, i));
|
||||
+ fb_info->dev = NULL;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL(unlink_framebuffer);
|
||||
+
|
||||
void remove_conflicting_framebuffers(struct apertures_struct *a,
|
||||
const char *name, bool primary)
|
||||
{
|
||||
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
|
||||
index a197731..a40c05e 100644
|
||||
--- a/drivers/video/udlfb.c
|
||||
+++ b/drivers/video/udlfb.c
|
||||
@@ -1739,7 +1739,7 @@ static void dlfb_usb_disconnect(struct usb_interface *interface)
|
||||
for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
|
||||
device_remove_file(info->dev, &fb_device_attrs[i]);
|
||||
device_remove_bin_file(info->dev, &edid_attr);
|
||||
-
|
||||
+ unlink_framebuffer(info);
|
||||
usb_set_intfdata(interface, NULL);
|
||||
|
||||
/* if clients still have us open, will be freed on last close */
|
||||
diff --git a/include/linux/fb.h b/include/linux/fb.h
|
||||
index c18122f..a395b8c 100644
|
||||
--- a/include/linux/fb.h
|
||||
+++ b/include/linux/fb.h
|
||||
@@ -1003,6 +1003,7 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
|
||||
/* drivers/video/fbmem.c */
|
||||
extern int register_framebuffer(struct fb_info *fb_info);
|
||||
extern int unregister_framebuffer(struct fb_info *fb_info);
|
||||
+extern int unlink_framebuffer(struct fb_info *fb_info);
|
||||
extern void remove_conflicting_framebuffers(struct apertures_struct *a,
|
||||
const char *name, bool primary);
|
||||
extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
|
||||
--
|
||||
1.7.6.5
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
From dadfe1ad137e6fbe251b4a5dc310840cfe414db4 Mon Sep 17 00:00:00 2001
|
||||
From: Josh Boyer <jwboyer@redhat.com>
|
||||
Date: Mon, 20 Feb 2012 15:28:39 -0500
|
||||
Subject: [PATCH] ums_realtek: do not use stack memory for DMA in
|
||||
__do_config_autodelink
|
||||
|
||||
__do_config_autodelink passes the data variable to the transport function.
|
||||
If the calling functions pass a stack variable, this will eventually trigger
|
||||
a DMA-API debug backtrace for mapping stack memory in the DMA buffer. Fix
|
||||
this by calling kmemdup for the passed data instead.
|
||||
|
||||
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
|
||||
---
|
||||
drivers/usb/storage/realtek_cr.c | 8 +++++++-
|
||||
1 files changed, 7 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c
|
||||
index d32f720..eee2a96 100644
|
||||
--- a/drivers/usb/storage/realtek_cr.c
|
||||
+++ b/drivers/usb/storage/realtek_cr.c
|
||||
@@ -507,9 +507,14 @@ static int __do_config_autodelink(struct us_data *us, u8 *data, u16 len)
|
||||
{
|
||||
int retval;
|
||||
u8 cmnd[12] = {0};
|
||||
+ u8 *buf;
|
||||
|
||||
US_DEBUGP("%s, addr = 0xfe47, len = %d\n", __FUNCTION__, len);
|
||||
|
||||
+ buf = kmemdup(data, len, GFP_NOIO);
|
||||
+ if (!buf)
|
||||
+ return USB_STOR_TRANSPORT_ERROR;
|
||||
+
|
||||
cmnd[0] = 0xF0;
|
||||
cmnd[1] = 0x0E;
|
||||
cmnd[2] = 0xfe;
|
||||
@@ -517,7 +522,8 @@ static int __do_config_autodelink(struct us_data *us, u8 *data, u16 len)
|
||||
cmnd[4] = (u8)(len >> 8);
|
||||
cmnd[5] = (u8)len;
|
||||
|
||||
- retval = rts51x_bulk_transport_special(us, 0, cmnd, 12, data, len, DMA_TO_DEVICE, NULL);
|
||||
+ retval = rts51x_bulk_transport_special(us, 0, cmnd, 12, buf, len, DMA_TO_DEVICE, NULL);
|
||||
+ kfree(buf);
|
||||
if (retval != USB_STOR_TRANSPORT_GOOD) {
|
||||
return -EIO;
|
||||
}
|
||||
--
|
||||
1.7.9
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
On Tue, 2012-01-31 at 09:26 -0500, Josh Boyer wrote:
|
||||
> On Wed, Jan 25, 2012 at 06:15:35PM -0500, Josh Boyer wrote:
|
||||
> > On Wed, Jan 25, 2012 at 02:04:08PM -0800, Suresh Siddha wrote:
|
||||
> > > On Wed, 2012-01-25 at 08:49 -0500, Josh Boyer wrote:
|
||||
> > > > [ 0.000000] IOAPIC[1]: apic_id 2, version 255, address 0xfec28000, GSI 24-279
|
||||
> > >
|
||||
> > > This looks indeed like a bogus entry probably returning all 1's for
|
||||
> > > RTE's etc. Can you please send me a dmesg with "apic=verbose" boot
|
||||
> > > parameter?
|
||||
> >
|
||||
> > Here you go:
|
||||
> >
|
||||
> > https://bugzilla.redhat.com/attachment.cgi?id=557552
|
||||
>
|
||||
> Was this helpful at all? I've been watching lkml for a related patch
|
||||
> in case I was missed on CC but haven't seen anything as of yet.
|
||||
|
||||
Yes, it was helpful. Something like the appended patch should ignore the
|
||||
bogus io-apic entry all together. As I can't test this, can you or the
|
||||
reporter give the appended patch a try and ack please?
|
||||
|
||||
thanks,
|
||||
suresh
|
||||
---
|
||||
|
||||
From: Suresh Siddha <suresh.b.siddha@intel.com>
|
||||
Subject: x86, ioapic: add register checks for bogus io-apic entries
|
||||
|
||||
With the recent changes to clear_IO_APIC_pin() which tries to clear
|
||||
remoteIRR bit explicitly, some of the users started to see
|
||||
"Unable to reset IRR for apic .." messages.
|
||||
|
||||
Close look shows that these are related to bogus IO-APIC entries which
|
||||
return's all 1's for their io-apic registers. And the above mentioned error
|
||||
messages are benign. But kernel should have ignored such io-apic's in the
|
||||
first place.
|
||||
|
||||
Check if register 0, 1, 2 of the listed io-apic are all 1's and ignore
|
||||
such io-apic.
|
||||
|
||||
Reported-by: Álvaro Castillo <midgoon@gmail.com>
|
||||
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
|
||||
---
|
||||
arch/x86/kernel/apic/io_apic.c | 26 ++++++++++++++++++++++++++
|
||||
1 files changed, 26 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
|
||||
index fb07275..953e54d 100644
|
||||
--- a/arch/x86/kernel/apic/io_apic.c
|
||||
+++ b/arch/x86/kernel/apic/io_apic.c
|
||||
@@ -3979,6 +3979,26 @@ static __init int bad_ioapic(unsigned long address)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static __init int bad_ioapic_regs(int idx)
|
||||
+{
|
||||
+ union IO_APIC_reg_00 reg_00;
|
||||
+ union IO_APIC_reg_01 reg_01;
|
||||
+ union IO_APIC_reg_02 reg_02;
|
||||
+
|
||||
+ reg_00.raw = io_apic_read(idx, 0);
|
||||
+ reg_01.raw = io_apic_read(idx, 1);
|
||||
+ reg_02.raw = io_apic_read(idx, 2);
|
||||
+
|
||||
+ if (reg_00.raw == -1 && reg_01.raw == -1 && reg_02.raw == -1) {
|
||||
+ printk(KERN_WARNING
|
||||
+ "I/O APIC 0x%x regs return all ones, skipping!\n",
|
||||
+ mpc_ioapic_addr(idx));
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
|
||||
{
|
||||
int idx = 0;
|
||||
@@ -3995,6 +4015,12 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
|
||||
ioapics[idx].mp_config.apicaddr = address;
|
||||
|
||||
set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
|
||||
+
|
||||
+ if (bad_ioapic_regs(idx)) {
|
||||
+ clear_fixmap(FIX_IO_APIC_BASE_0 + idx);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
ioapics[idx].mp_config.apicid = io_apic_unique_id(id);
|
||||
ioapics[idx].mp_config.apicver = io_apic_get_version(idx);
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue