diff options
| -rw-r--r-- | arch/x86/include/asm/io.h | 1 | ||||
| -rw-r--r-- | arch/x86/mm/ioremap.c | 5 | ||||
| -rw-r--r-- | arch/x86/xen/mmu.c | 26 |
3 files changed, 24 insertions, 8 deletions
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 30a3e977612..66aee6c4123 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h | |||
| @@ -348,6 +348,7 @@ extern void __iomem *early_memremap(resource_size_t phys_addr, | |||
| 348 | unsigned long size); | 348 | unsigned long size); |
| 349 | extern void early_iounmap(void __iomem *addr, unsigned long size); | 349 | extern void early_iounmap(void __iomem *addr, unsigned long size); |
| 350 | extern void fixup_early_ioremap(void); | 350 | extern void fixup_early_ioremap(void); |
| 351 | extern bool is_early_ioremap_ptep(pte_t *ptep); | ||
| 351 | 352 | ||
| 352 | #define IO_SPACE_LIMIT 0xffff | 353 | #define IO_SPACE_LIMIT 0xffff |
| 353 | 354 | ||
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 3ba6e0608c5..0369843511d 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c | |||
| @@ -362,6 +362,11 @@ static inline pte_t * __init early_ioremap_pte(unsigned long addr) | |||
| 362 | return &bm_pte[pte_index(addr)]; | 362 | return &bm_pte[pte_index(addr)]; |
| 363 | } | 363 | } |
| 364 | 364 | ||
| 365 | bool __init is_early_ioremap_ptep(pte_t *ptep) | ||
| 366 | { | ||
| 367 | return ptep >= &bm_pte[0] && ptep < &bm_pte[PAGE_SIZE/sizeof(pte_t)]; | ||
| 368 | } | ||
| 369 | |||
| 365 | static unsigned long slot_virt[FIX_BTMAPS_SLOTS] __initdata; | 370 | static unsigned long slot_virt[FIX_BTMAPS_SLOTS] __initdata; |
| 366 | 371 | ||
| 367 | void __init early_ioremap_init(void) | 372 | void __init early_ioremap_init(void) |
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 4fe04ac0bae..7d55e9ee3a7 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
| @@ -56,6 +56,7 @@ | |||
| 56 | #include <asm/e820.h> | 56 | #include <asm/e820.h> |
| 57 | #include <asm/linkage.h> | 57 | #include <asm/linkage.h> |
| 58 | #include <asm/page.h> | 58 | #include <asm/page.h> |
| 59 | #include <asm/init.h> | ||
| 59 | 60 | ||
| 60 | #include <asm/xen/hypercall.h> | 61 | #include <asm/xen/hypercall.h> |
| 61 | #include <asm/xen/hypervisor.h> | 62 | #include <asm/xen/hypervisor.h> |
| @@ -360,7 +361,8 @@ void make_lowmem_page_readonly(void *vaddr) | |||
| 360 | unsigned int level; | 361 | unsigned int level; |
| 361 | 362 | ||
| 362 | pte = lookup_address(address, &level); | 363 | pte = lookup_address(address, &level); |
| 363 | BUG_ON(pte == NULL); | 364 | if (pte == NULL) |
| 365 | return; /* vaddr missing */ | ||
| 364 | 366 | ||
| 365 | ptev = pte_wrprotect(*pte); | 367 | ptev = pte_wrprotect(*pte); |
| 366 | 368 | ||
| @@ -375,7 +377,8 @@ void make_lowmem_page_readwrite(void *vaddr) | |||
| 375 | unsigned int level; | 377 | unsigned int level; |
| 376 | 378 | ||
| 377 | pte = lookup_address(address, &level); | 379 | pte = lookup_address(address, &level); |
| 378 | BUG_ON(pte == NULL); | 380 | if (pte == NULL) |
| 381 | return; /* vaddr missing */ | ||
| 379 | 382 | ||
| 380 | ptev = pte_mkwrite(*pte); | 383 | ptev = pte_mkwrite(*pte); |
| 381 | 384 | ||
| @@ -1509,13 +1512,25 @@ static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd) | |||
| 1509 | #endif | 1512 | #endif |
| 1510 | } | 1513 | } |
| 1511 | 1514 | ||
| 1512 | #ifdef CONFIG_X86_32 | ||
| 1513 | static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte) | 1515 | static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte) |
| 1514 | { | 1516 | { |
| 1517 | unsigned long pfn = pte_pfn(pte); | ||
| 1518 | |||
| 1519 | #ifdef CONFIG_X86_32 | ||
| 1515 | /* If there's an existing pte, then don't allow _PAGE_RW to be set */ | 1520 | /* If there's an existing pte, then don't allow _PAGE_RW to be set */ |
| 1516 | if (pte_val_ma(*ptep) & _PAGE_PRESENT) | 1521 | if (pte_val_ma(*ptep) & _PAGE_PRESENT) |
| 1517 | pte = __pte_ma(((pte_val_ma(*ptep) & _PAGE_RW) | ~_PAGE_RW) & | 1522 | pte = __pte_ma(((pte_val_ma(*ptep) & _PAGE_RW) | ~_PAGE_RW) & |
| 1518 | pte_val_ma(pte)); | 1523 | pte_val_ma(pte)); |
| 1524 | #endif | ||
| 1525 | |||
| 1526 | /* | ||
| 1527 | * If the new pfn is within the range of the newly allocated | ||
| 1528 | * kernel pagetable, and it isn't being mapped into an | ||
| 1529 | * early_ioremap fixmap slot, make sure it is RO. | ||
| 1530 | */ | ||
| 1531 | if (!is_early_ioremap_ptep(ptep) && | ||
| 1532 | pfn >= e820_table_start && pfn < e820_table_end) | ||
| 1533 | pte = pte_wrprotect(pte); | ||
| 1519 | 1534 | ||
| 1520 | return pte; | 1535 | return pte; |
| 1521 | } | 1536 | } |
| @@ -1528,7 +1543,6 @@ static __init void xen_set_pte_init(pte_t *ptep, pte_t pte) | |||
| 1528 | 1543 | ||
| 1529 | xen_set_pte(ptep, pte); | 1544 | xen_set_pte(ptep, pte); |
| 1530 | } | 1545 | } |
| 1531 | #endif | ||
| 1532 | 1546 | ||
| 1533 | static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn) | 1547 | static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn) |
| 1534 | { | 1548 | { |
| @@ -1973,11 +1987,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = { | |||
| 1973 | .alloc_pmd_clone = paravirt_nop, | 1987 | .alloc_pmd_clone = paravirt_nop, |
| 1974 | .release_pmd = xen_release_pmd_init, | 1988 | .release_pmd = xen_release_pmd_init, |
| 1975 | 1989 | ||
| 1976 | #ifdef CONFIG_X86_64 | ||
| 1977 | .set_pte = xen_set_pte, | ||
| 1978 | #else | ||
| 1979 | .set_pte = xen_set_pte_init, | 1990 | .set_pte = xen_set_pte_init, |
| 1980 | #endif | ||
| 1981 | .set_pte_at = xen_set_pte_at, | 1991 | .set_pte_at = xen_set_pte_at, |
| 1982 | .set_pmd = xen_set_pmd_hyper, | 1992 | .set_pmd = xen_set_pmd_hyper, |
| 1983 | 1993 | ||
