All of lore.kernel.org
 help / color / mirror / Atom feed
From: Zachary Amsden <zach@vmware.com>
To: Virtualization Mailing List <virtualization@lists.osdl.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Linus Torvalds <torvalds@osdl.org>, Chris Wright <chrisw@sous-so>
Cc: Ben Collins <ben.collins@ubuntu.com>
Subject: [PATCH] Fix lazy mode vmalloc synchronization for paravirt
Date: Tue, 21 Aug 2007 18:30:36 -0700	[thread overview]
Message-ID: <46CB91BC.2010808@vmware.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 622 bytes --]

Found this looping Ubuntu installs with VMI.

If unlucky enough to hit a vmalloc sync fault during a lazy mode 
operation (from an IRQ handler for a module which was not yet populated 
in current page directory, or from inside copy_one_pte, which touches 
swap_map, and hit in an unused 4M region), the required PDE update would 
never get flushed, causing an infinite page fault loop.

This bug affects any paravirt-ops backend which uses lazy updates, I 
believe that makes it a bug in Xen, VMI and lguest.  It only happens on 
LOWMEM kernels.

Currently for 2.6.23, but we'll want to backport to -stable as well.

Zach

[-- Attachment #2: i386-linus-vmalloc-paravirt-fix.patch --]
[-- Type: text/x-patch, Size: 823 bytes --]

    Touching vmalloc memory in the middle of a lazy mode update can generate
    a kernel PDE update, which must be flushed immediately.  The fix is to
    leave lazy mode when doing a vmalloc sync.
    
    Signed-off-by: Zachary Amsden <zach@vmware.com>

diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
index 01ffdd4..fcb38e7 100644
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -249,9 +249,10 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
 	pmd_k = pmd_offset(pud_k, address);
 	if (!pmd_present(*pmd_k))
 		return NULL;
-	if (!pmd_present(*pmd))
+	if (!pmd_present(*pmd)) {
 		set_pmd(pmd, *pmd_k);
-	else
+		arch_flush_lazy_mmu_mode();
+	} else
 		BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
 	return pmd_k;
 }

WARNING: multiple messages have this Message-ID (diff)
From: Zachary Amsden <zach@vmware.com>
To: Virtualization Mailing List <virtualization@lists.osdl.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Linus Torvalds <torvalds@osdl.org>,
	Chris Wright <chrisw@sous-sol.org>,
	Rusty Russell <rusty@rustcorp.com.au>,
	Jeremy Fitzhardinge <jeremy@goop.org>, Andi Kleen <ak@suse.de>,
	Andrew Morton <akpm@osdl.org>
Cc: Ben Collins <ben.collins@ubuntu.com>
Subject: [PATCH] Fix lazy mode vmalloc synchronization for paravirt
Date: Tue, 21 Aug 2007 18:30:36 -0700	[thread overview]
Message-ID: <46CB91BC.2010808@vmware.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 622 bytes --]

Found this looping Ubuntu installs with VMI.

If unlucky enough to hit a vmalloc sync fault during a lazy mode 
operation (from an IRQ handler for a module which was not yet populated 
in current page directory, or from inside copy_one_pte, which touches 
swap_map, and hit in an unused 4M region), the required PDE update would 
never get flushed, causing an infinite page fault loop.

This bug affects any paravirt-ops backend which uses lazy updates, I 
believe that makes it a bug in Xen, VMI and lguest.  It only happens on 
LOWMEM kernels.

Currently for 2.6.23, but we'll want to backport to -stable as well.

Zach

[-- Attachment #2: i386-linus-vmalloc-paravirt-fix.patch --]
[-- Type: text/x-patch, Size: 823 bytes --]

    Touching vmalloc memory in the middle of a lazy mode update can generate
    a kernel PDE update, which must be flushed immediately.  The fix is to
    leave lazy mode when doing a vmalloc sync.
    
    Signed-off-by: Zachary Amsden <zach@vmware.com>

diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
index 01ffdd4..fcb38e7 100644
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -249,9 +249,10 @@ static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
 	pmd_k = pmd_offset(pud_k, address);
 	if (!pmd_present(*pmd_k))
 		return NULL;
-	if (!pmd_present(*pmd))
+	if (!pmd_present(*pmd)) {
 		set_pmd(pmd, *pmd_k);
-	else
+		arch_flush_lazy_mmu_mode();
+	} else
 		BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k));
 	return pmd_k;
 }

             reply	other threads:[~2007-08-22  1:30 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-08-22  1:30 Zachary Amsden [this message]
2007-08-22  1:30 ` [PATCH] Fix lazy mode vmalloc synchronization for paravirt Zachary Amsden
2007-08-22  6:28 ` Jeremy Fitzhardinge
2007-08-22  6:52   ` Zachary Amsden

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=46CB91BC.2010808@vmware.com \
    --to=zach@vmware.com \
    --cc=ben.collins@ubuntu.com \
    --cc=chrisw@sous-so \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@osdl.org \
    --cc=virtualization@lists.osdl.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is 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.