All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86: Fix set_memory_wc related corruption
@ 2009-07-30 21:43 Pallipadi, Venkatesh
  2009-07-31  0:27 ` Dave Airlie
  2009-07-31  2:07 ` [tip:x86/urgent] x86, pat: " tip-bot for Pallipadi, Venkatesh
  0 siblings, 2 replies; 3+ messages in thread
From: Pallipadi, Venkatesh @ 2009-07-30 21:43 UTC (permalink / raw)
  To: Ingo Molnar, H. Peter Anvin, Thomas Gleixner
  Cc: linux-kernel, stable, suresh.b.siddha, Jerome Glisse


Changeset 3869c4aa18835c8c61b44bd0f3ace36e9d3b5bd0
that went in after 2.6.30-rc1 was a seemingly small change to _set_memory_wc()
to make it complaint with SDM requirements. But, introduced a nasty bug, which
can result in crash and/or strange corruptions when set_memory_wc is used.
One such crash reported here
http://lkml.org/lkml/2009/7/30/94

Actually, that changeset introduced two bugs.
* change_page_attr_set() takes &addr as first argument and can the addr value
  might have changed on return, even for single page change_page_attr_set()
  call. That will make the second change_page_attr_set() in this routine
  operate on unrelated addr, that can eventually cause strange corruptions
  and bad page state crash.
* The second change_page_attr_set() call, before setting _PAGE_CACHE_WC, should
  clear the earlier _PAGE_CACHE_UC_MINUS, as otherwise cache attribute will not
  be WC (will be UC instead).

The patch below fixes both these problems. Sending a single patch to fix both
the problems, as the change is to the same line of code. The change to have a
addr_copy is not very clean. But, it is simpler than making more changes
through various routines in pageattr.c.

A huge thanks to Jerome for reporting this problem and providing a simple test
case that helped us root cause the problem.

Reported-by: Jerome Glisse <glisse@freedesktop.org>

Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
---

Patch needed for 2.6.30-stable as well

 arch/x86/mm/pageattr.c |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 1b734d7..895d90e 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -997,12 +997,15 @@ EXPORT_SYMBOL(set_memory_array_uc);
 int _set_memory_wc(unsigned long addr, int numpages)
 {
 	int ret;
+	unsigned long addr_copy = addr;
+
 	ret = change_page_attr_set(&addr, numpages,
 				    __pgprot(_PAGE_CACHE_UC_MINUS), 0);
-
 	if (!ret) {
-		ret = change_page_attr_set(&addr, numpages,
-				    __pgprot(_PAGE_CACHE_WC), 0);
+		ret = change_page_attr_set_clr(&addr_copy, numpages,
+					       __pgprot(_PAGE_CACHE_WC),
+					       __pgprot(_PAGE_CACHE_MASK),
+					       0, 0, NULL);
 	}
 	return ret;
 }
-- 
1.6.0.6


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] x86: Fix set_memory_wc related corruption
  2009-07-30 21:43 [PATCH] x86: Fix set_memory_wc related corruption Pallipadi, Venkatesh
@ 2009-07-31  0:27 ` Dave Airlie
  2009-07-31  2:07 ` [tip:x86/urgent] x86, pat: " tip-bot for Pallipadi, Venkatesh
  1 sibling, 0 replies; 3+ messages in thread
From: Dave Airlie @ 2009-07-31  0:27 UTC (permalink / raw)
  To: Pallipadi, Venkatesh
  Cc: Ingo Molnar, H. Peter Anvin, Thomas Gleixner, linux-kernel,
	stable, suresh.b.siddha, Jerome Glisse

On Fri, Jul 31, 2009 at 7:43 AM, Pallipadi,
Venkatesh<venkatesh.pallipadi@intel.com> wrote:
>
> Changeset 3869c4aa18835c8c61b44bd0f3ace36e9d3b5bd0
> that went in after 2.6.30-rc1 was a seemingly small change to _set_memory_wc()
> to make it complaint with SDM requirements. But, introduced a nasty bug, which
> can result in crash and/or strange corruptions when set_memory_wc is used.
> One such crash reported here
> http://lkml.org/lkml/2009/7/30/94
>
> Actually, that changeset introduced two bugs.
> * change_page_attr_set() takes &addr as first argument and can the addr value
>  might have changed on return, even for single page change_page_attr_set()
>  call. That will make the second change_page_attr_set() in this routine
>  operate on unrelated addr, that can eventually cause strange corruptions
>  and bad page state crash.
> * The second change_page_attr_set() call, before setting _PAGE_CACHE_WC, should
>  clear the earlier _PAGE_CACHE_UC_MINUS, as otherwise cache attribute will not
>  be WC (will be UC instead).
>
> The patch below fixes both these problems. Sending a single patch to fix both
> the problems, as the change is to the same line of code. The change to have a
> addr_copy is not very clean. But, it is simpler than making more changes
> through various routines in pageattr.c.
>
> A huge thanks to Jerome for reporting this problem and providing a simple test
> case that helped us root cause the problem.
>
> Reported-by: Jerome Glisse <glisse@freedesktop.org>
>
> Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
> Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>

Acked-by: Dave Airlie <airlied@redhat.com>

please urgent this, so I don't get blamed for radeon KMS not working ;-)

Dave.

> ---
>
> Patch needed for 2.6.30-stable as well
>
>  arch/x86/mm/pageattr.c |    9 ++++++---
>  1 files changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
> index 1b734d7..895d90e 100644
> --- a/arch/x86/mm/pageattr.c
> +++ b/arch/x86/mm/pageattr.c
> @@ -997,12 +997,15 @@ EXPORT_SYMBOL(set_memory_array_uc);
>  int _set_memory_wc(unsigned long addr, int numpages)
>  {
>        int ret;
> +       unsigned long addr_copy = addr;
> +
>        ret = change_page_attr_set(&addr, numpages,
>                                    __pgprot(_PAGE_CACHE_UC_MINUS), 0);
> -
>        if (!ret) {
> -               ret = change_page_attr_set(&addr, numpages,
> -                                   __pgprot(_PAGE_CACHE_WC), 0);
> +               ret = change_page_attr_set_clr(&addr_copy, numpages,
> +                                              __pgprot(_PAGE_CACHE_WC),
> +                                              __pgprot(_PAGE_CACHE_MASK),
> +                                              0, 0, NULL);
>        }
>        return ret;
>  }
> --
> 1.6.0.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [tip:x86/urgent] x86, pat: Fix set_memory_wc related corruption
  2009-07-30 21:43 [PATCH] x86: Fix set_memory_wc related corruption Pallipadi, Venkatesh
  2009-07-31  0:27 ` Dave Airlie
@ 2009-07-31  2:07 ` tip-bot for Pallipadi, Venkatesh
  1 sibling, 0 replies; 3+ messages in thread
From: tip-bot for Pallipadi, Venkatesh @ 2009-07-31  2:07 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, venkatesh.pallipadi, suresh.b.siddha,
	airlied, tglx, glisse

Commit-ID:  bdc6340f4eb68295b1e7c0ade2356b56dca93d93
Gitweb:     http://git.kernel.org/tip/bdc6340f4eb68295b1e7c0ade2356b56dca93d93
Author:     Pallipadi, Venkatesh <venkatesh.pallipadi@intel.com>
AuthorDate: Thu, 30 Jul 2009 14:43:19 -0700
Committer:  H. Peter Anvin <hpa@zytor.com>
CommitDate: Thu, 30 Jul 2009 17:48:34 -0700

x86, pat: Fix set_memory_wc related corruption

Changeset 3869c4aa18835c8c61b44bd0f3ace36e9d3b5bd0
that went in after 2.6.30-rc1 was a seemingly small change to _set_memory_wc()
to make it complaint with SDM requirements. But, introduced a nasty bug, which
can result in crash and/or strange corruptions when set_memory_wc is used.
One such crash reported here
http://lkml.org/lkml/2009/7/30/94

Actually, that changeset introduced two bugs.
* change_page_attr_set() takes &addr as first argument and can the addr value
  might have changed on return, even for single page change_page_attr_set()
  call. That will make the second change_page_attr_set() in this routine
  operate on unrelated addr, that can eventually cause strange corruptions
  and bad page state crash.
* The second change_page_attr_set() call, before setting _PAGE_CACHE_WC, should
  clear the earlier _PAGE_CACHE_UC_MINUS, as otherwise cache attribute will not
  be WC (will be UC instead).

The patch below fixes both these problems. Sending a single patch to fix both
the problems, as the change is to the same line of code. The change to have a
addr_copy is not very clean. But, it is simpler than making more changes
through various routines in pageattr.c.

A huge thanks to Jerome for reporting this problem and providing a simple test
case that helped us root cause the problem.

Reported-by: Jerome Glisse <glisse@freedesktop.org>
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
LKML-Reference: <20090730214319.GA1889@linux-os.sc.intel.com>
Acked-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>


---
 arch/x86/mm/pageattr.c |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 1b734d7..895d90e 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -997,12 +997,15 @@ EXPORT_SYMBOL(set_memory_array_uc);
 int _set_memory_wc(unsigned long addr, int numpages)
 {
 	int ret;
+	unsigned long addr_copy = addr;
+
 	ret = change_page_attr_set(&addr, numpages,
 				    __pgprot(_PAGE_CACHE_UC_MINUS), 0);
-
 	if (!ret) {
-		ret = change_page_attr_set(&addr, numpages,
-				    __pgprot(_PAGE_CACHE_WC), 0);
+		ret = change_page_attr_set_clr(&addr_copy, numpages,
+					       __pgprot(_PAGE_CACHE_WC),
+					       __pgprot(_PAGE_CACHE_MASK),
+					       0, 0, NULL);
 	}
 	return ret;
 }

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-07-31  2:10 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-30 21:43 [PATCH] x86: Fix set_memory_wc related corruption Pallipadi, Venkatesh
2009-07-31  0:27 ` Dave Airlie
2009-07-31  2:07 ` [tip:x86/urgent] x86, pat: " tip-bot for Pallipadi, Venkatesh

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.