diff options
author | Ian Campbell <ian.campbell@citrix.com> | 2010-02-26 12:16:00 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-03-15 12:06:51 -0400 |
commit | b8cfe68deb636a652d17d2de8e4a61f19a906289 (patch) | |
tree | 1d284e0e5025a35688bd8ec55bf259e20194fc2f /arch | |
parent | 3ed5b5c623ef901be4f7e6c7e1a0d576f0e30af4 (diff) |
x86, xen: Disable highmem PTE allocation even when CONFIG_HIGHPTE=y
commit 817a824b75b1475f1b067c8cee318c7b4d66fcde upstream.
There's a path in the pagefault code where the kernel deliberately
breaks its own locking rules by kmapping a high pte page without
holding the pagetable lock (in at least page_check_address). This
breaks Xen's ability to track the pinned/unpinned state of the
page. There does not appear to be a viable workaround for this
behaviour so simply disable HIGHPTE for all Xen guests.
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
LKML-Reference: <1267204562-11844-1-git-send-email-ian.campbell@citrix.com>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Pasi Kärkkäinen <pasik@iki.fi>
Cc: <xen-devel@lists.xensource.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/xen/enlighten.c | 7 | ||||
-rw-r--r-- | arch/x86/xen/mmu.c | 11 |
2 files changed, 13 insertions, 5 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 36daccb68642..b607239c1ba8 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <asm/traps.h> | 50 | #include <asm/traps.h> |
51 | #include <asm/setup.h> | 51 | #include <asm/setup.h> |
52 | #include <asm/desc.h> | 52 | #include <asm/desc.h> |
53 | #include <asm/pgalloc.h> | ||
53 | #include <asm/pgtable.h> | 54 | #include <asm/pgtable.h> |
54 | #include <asm/tlbflush.h> | 55 | #include <asm/tlbflush.h> |
55 | #include <asm/reboot.h> | 56 | #include <asm/reboot.h> |
@@ -1094,6 +1095,12 @@ asmlinkage void __init xen_start_kernel(void) | |||
1094 | 1095 | ||
1095 | __supported_pte_mask |= _PAGE_IOMAP; | 1096 | __supported_pte_mask |= _PAGE_IOMAP; |
1096 | 1097 | ||
1098 | /* | ||
1099 | * Prevent page tables from being allocated in highmem, even | ||
1100 | * if CONFIG_HIGHPTE is enabled. | ||
1101 | */ | ||
1102 | __userpte_alloc_gfp &= ~__GFP_HIGHMEM; | ||
1103 | |||
1097 | /* Work out if we support NX */ | 1104 | /* Work out if we support NX */ |
1098 | x86_configure_nx(); | 1105 | x86_configure_nx(); |
1099 | 1106 | ||
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index bf4cd6bfe959..350a3deedf25 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -1432,14 +1432,15 @@ static void *xen_kmap_atomic_pte(struct page *page, enum km_type type) | |||
1432 | { | 1432 | { |
1433 | pgprot_t prot = PAGE_KERNEL; | 1433 | pgprot_t prot = PAGE_KERNEL; |
1434 | 1434 | ||
1435 | /* | ||
1436 | * We disable highmem allocations for page tables so we should never | ||
1437 | * see any calls to kmap_atomic_pte on a highmem page. | ||
1438 | */ | ||
1439 | BUG_ON(PageHighMem(page)); | ||
1440 | |||
1435 | if (PagePinned(page)) | 1441 | if (PagePinned(page)) |
1436 | prot = PAGE_KERNEL_RO; | 1442 | prot = PAGE_KERNEL_RO; |
1437 | 1443 | ||
1438 | if (0 && PageHighMem(page)) | ||
1439 | printk("mapping highpte %lx type %d prot %s\n", | ||
1440 | page_to_pfn(page), type, | ||
1441 | (unsigned long)pgprot_val(prot) & _PAGE_RW ? "WRITE" : "READ"); | ||
1442 | |||
1443 | return kmap_atomic_prot(page, type, prot); | 1444 | return kmap_atomic_prot(page, type, prot); |
1444 | } | 1445 | } |
1445 | #endif | 1446 | #endif |