| 21 |
LKML-Reference: <4CB88A4C.1080305@goop.org> |
LKML-Reference: <4CB88A4C.1080305@goop.org> |
| 22 |
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> |
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> |
| 23 |
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> |
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> |
| 24 |
|
[bwh: Adjust context to apply after backported commit |
| 25 |
|
a79e53d85683c6dd9f99c90511028adc2043031f 'x86/mm: Fix pgd_lock deadlock'] |
| 26 |
--- |
--- |
| 27 |
arch/x86/include/asm/pgtable.h | 2 ++ |
arch/x86/include/asm/pgtable.h | 2 ++ |
| 28 |
arch/x86/mm/fault.c | 11 ++++++++++- |
arch/x86/mm/fault.c | 11 ++++++++++- |
| 30 |
arch/x86/mm/pgtable.c | 20 +++++++++++++++++--- |
arch/x86/mm/pgtable.c | 20 +++++++++++++++++--- |
| 31 |
4 files changed, 36 insertions(+), 4 deletions(-) |
4 files changed, 36 insertions(+), 4 deletions(-) |
| 32 |
|
|
|
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h |
|
|
index 2d0a33b..ada823a 100644 |
|
| 33 |
--- a/arch/x86/include/asm/pgtable.h |
--- a/arch/x86/include/asm/pgtable.h |
| 34 |
+++ b/arch/x86/include/asm/pgtable.h |
+++ b/arch/x86/include/asm/pgtable.h |
| 35 |
@@ -28,6 +28,8 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; |
@@ -28,6 +28,8 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; |
| 41 |
#ifdef CONFIG_PARAVIRT |
#ifdef CONFIG_PARAVIRT |
| 42 |
#include <asm/paravirt.h> |
#include <asm/paravirt.h> |
| 43 |
#else /* !CONFIG_PARAVIRT */ |
#else /* !CONFIG_PARAVIRT */ |
|
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c |
|
|
index caec229..6c27c39 100644 |
|
| 44 |
--- a/arch/x86/mm/fault.c |
--- a/arch/x86/mm/fault.c |
| 45 |
+++ b/arch/x86/mm/fault.c |
+++ b/arch/x86/mm/fault.c |
| 46 |
@@ -229,7 +229,16 @@ void vmalloc_sync_all(void) |
@@ -229,7 +229,16 @@ void vmalloc_sync_all(void) |
| 47 |
|
|
| 48 |
spin_lock_irqsave(&pgd_lock, flags); |
spin_lock(&pgd_lock); |
| 49 |
list_for_each_entry(page, &pgd_list, lru) { |
list_for_each_entry(page, &pgd_list, lru) { |
| 50 |
- if (!vmalloc_sync_one(page_address(page), address)) |
- if (!vmalloc_sync_one(page_address(page), address)) |
| 51 |
+ spinlock_t *pgt_lock; |
+ spinlock_t *pgt_lock; |
| 60 |
+ if (!ret) |
+ if (!ret) |
| 61 |
break; |
break; |
| 62 |
} |
} |
| 63 |
spin_unlock_irqrestore(&pgd_lock, flags); |
spin_unlock(&pgd_lock); |
| 64 |
@@ -349,11 +349,19 @@ |
@@ -349,11 +349,19 @@ |
| 65 |
spin_lock_irqsave(&pgd_lock, flags); |
spin_lock(&pgd_lock); |
| 66 |
list_for_each_entry(page, &pgd_list, lru) { |
list_for_each_entry(page, &pgd_list, lru) { |
| 67 |
pgd_t *pgd; |
pgd_t *pgd; |
| 68 |
+ spinlock_t *pgt_lock; |
+ spinlock_t *pgt_lock; |
| 79 |
+ |
+ |
| 80 |
+ spin_unlock(pgt_lock); |
+ spin_unlock(pgt_lock); |
| 81 |
} |
} |
| 82 |
spin_unlock_irqrestore(&pgd_lock, flags); |
spin_unlock(&pgd_lock); |
| 83 |
} |
} |
|
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c |
|
|
index 5c4ee42..c70e57d 100644 |
|
| 84 |
--- a/arch/x86/mm/pgtable.c |
--- a/arch/x86/mm/pgtable.c |
| 85 |
+++ b/arch/x86/mm/pgtable.c |
+++ b/arch/x86/mm/pgtable.c |
| 86 |
@@ -87,7 +87,19 @@ static inline void pgd_list_del(pgd_t *pgd) |
@@ -87,7 +87,19 @@ static inline void pgd_list_del(pgd_t *pgd) |
| 118 |
static void pgd_dtor(pgd_t *pgd) |
static void pgd_dtor(pgd_t *pgd) |
| 119 |
@@ -272,7 +286,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm) |
@@ -272,7 +286,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm) |
| 120 |
*/ |
*/ |
| 121 |
spin_lock_irqsave(&pgd_lock, flags); |
spin_lock(&pgd_lock); |
| 122 |
|
|
| 123 |
- pgd_ctor(pgd); |
- pgd_ctor(pgd); |
| 124 |
+ pgd_ctor(mm, pgd); |
+ pgd_ctor(mm, pgd); |
| 125 |
pgd_prepopulate_pmd(mm, pgd, pmds); |
pgd_prepopulate_pmd(mm, pgd, pmds); |
| 126 |
|
|
| 127 |
spin_unlock_irqrestore(&pgd_lock, flags); |
spin_unlock(&pgd_lock); |
|
-- |
|
|
1.7.4.1 |
|
|
|
|